Ansible : organize my playbooks, inventories and roles

Better is to have one ansible.cfg, one inventory. You list all the hosts in the inventory file, you can even put hosts in a group if they are similar to each other, eg: webservers.

Roles you share between all your hosts. When making your playbook, you can then apply these to certain hosts or certain host groups so that they don’t get applied to the hosts where you do not want them to be applied.

Eg, in inventory:

[webapps]
campanula
dedibox

then for a task, or importing tasks/roles, etc:

  tasks:
    - name: Creating /etc/myissue if in webapps group
      copy:
        content: "Web Application Server"
        dest: /etc/myissue
      when: '"webapps" in group_names'

or:

  tasks:
    - name: Adding repositories
      import_tasks: tasks/add_repos.yml

you can see the when option. You can also use things like ansible facts if you want to pull out the hostname to apply it to a single host rather than group.

The idea is to keep it simple to save repeating yourself for each host, group or whatever. Make it more dynamic.

You can also use ansible-galaxy to create directory structures for roles, eg:

root@redmine:~/playbooks# ansible-galaxy role init mytestrole
- Role mytestrole was created successfully

root@redmine:~/playbooks# cd mytestrole/

root@redmine:~/playbooks/mytestrole# tree
.
├── defaults
│   └── main.yml
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

6 directories, 8 files

you can then set up that role with default variables, handlers for restarting services once changes are applied, relevant tasks that need to be run, eg: ensure firewalld installed and running, or httpd installed and running. That role can then be used for multiple hosts. Even in a when field, you can set up tasks o be for multiple versions of Linux, so:

when: ansible_distribution == "Debian"

Depending on ansible version, instead of using the apt or dnf option, there is a package option so irrespective of distro, be it Debian, Ubuntu, Rocky, it will use the appropriate package manager itself and save you duplicating tasks when using apt or dnf in the playbook to install packages. With that example, you don’t even need to use when to differentiate Debian/Ubuntu with say Rocky which would use dnf - because package will automatically know.

Eg:

  tasks:
    - name: Install firewalld
      package:
        name: firewalld
        state: present

instead of:

  tasks:
    - name: Install firewalld
      dnf:
        name: firewalld
        state: present
      when: ansible_distribution == "Rocky"

with when you can also use or and, so you could apply something to multiple distributions.

when: (ansible_distribution == "RedHat" or ansible_distribution == "Rocky") and ansible_distribution_major_version == "8"