What Is Ansible Galaxy?

Ansible Galaxy is the community hub for sharing Ansible roles and collections. Instead of writing everything from scratch, install pre-built roles for common tasks — Nginx, Docker, PostgreSQL, Kubernetes — and collections for vendor-specific modules (AWS, Azure, VMware). The ansible-galaxy CLI manages installation, versioning, and dependency resolution.

Install a Role

# Install from Galaxy
ansible-galaxy role install geerlingguy.docker

# Install specific version
ansible-galaxy role install geerlingguy.docker,7.1.0

# Install to custom path
ansible-galaxy role install geerlingguy.docker -p ./roles/

# Install from Git
ansible-galaxy role install git+https://github.com/geerlingguy/ansible-role-docker.git

# Install from Git with version tag
ansible-galaxy role install git+https://github.com/geerlingguy/ansible-role-docker.git,7.1.0

Use in a playbook:

---
- name: Install Docker
  hosts: all
  become: true
  roles:
    - geerlingguy.docker

Install a Collection

# Install from Galaxy
ansible-galaxy collection install community.general

# Install specific version
ansible-galaxy collection install community.general:9.0.0

# Install from a tarball
ansible-galaxy collection install ./community-general-9.0.0.tar.gz

# Install to custom path
ansible-galaxy collection install community.general -p ./collections/

Requirements File

Define all dependencies in one file and install them together:

requirements.yml:

---
roles:
  - name: geerlingguy.docker
    version: "7.1.0"
  - name: geerlingguy.nginx
  - name: geerlingguy.postgresql
    version: "3.5.0"
  # From Git
  - src: https://github.com/elastic/ansible-elasticsearch.git
    name: elastic.elasticsearch
    version: "v7.17.0"

collections:
  - name: community.general
    version: ">=9.0.0"
  - name: ansible.posix
  - name: community.postgresql
    version: "3.6.0"
  - name: kubernetes.core
  - name: amazon.aws
    version: ">=7.0.0"

Install everything:

# Install all roles and collections
ansible-galaxy install -r requirements.yml

# Force reinstall (update)
ansible-galaxy install -r requirements.yml --force

# Install only roles
ansible-galaxy role install -r requirements.yml

# Install only collections
ansible-galaxy collection install -r requirements.yml

List Installed

# List installed roles
ansible-galaxy role list

# List installed collections
ansible-galaxy collection list

# Show details of a specific collection
ansible-galaxy collection list community.general

Remove

# Remove a role
ansible-galaxy role remove geerlingguy.docker

# Remove a collection (manual — delete the directory)
rm -rf ~/.ansible/collections/ansible_collections/community/general

Create Your Own Role

# Initialize a new role structure
ansible-galaxy role init my_custom_role

This creates:

my_custom_role/
├── README.md
├── defaults/
│   └── main.yml          # Default variables (overridable)
├── files/                 # Static files
├── handlers/
│   └── main.yml          # Handlers
├── meta/
│   └── main.yml          # Role metadata and dependencies
├── tasks/
│   └── main.yml          # Main task list
├── templates/             # Jinja2 templates
├── tests/
│   ├── inventory
│   └── test.yml
└── vars/
    └── main.yml          # Role variables (high priority)

Example Role

roles/myapp/tasks/main.yml:

---
- name: Create app group
  ansible.builtin.group:
    name: "{{ myapp_group }}"
    state: present

- name: Create app user
  ansible.builtin.user:
    name: "{{ myapp_user }}"
    group: "{{ myapp_group }}"
    system: true
    shell: /usr/sbin/nologin

- name: Create directories
  ansible.builtin.file:
    path: "{{ item }}"
    state: directory
    owner: "{{ myapp_user }}"
    group: "{{ myapp_group }}"
    mode: "0755"
  loop:
    - "{{ myapp_install_dir }}"
    - "{{ myapp_log_dir }}"

- name: Deploy config
  ansible.builtin.template:
    src: config.yml.j2
    dest: "{{ myapp_install_dir }}/config.yml"
    owner: "{{ myapp_user }}"
    mode: "0640"
  notify: Restart myapp

roles/myapp/defaults/main.yml:

---
myapp_user: myapp
myapp_group: myapp
myapp_install_dir: /opt/myapp
myapp_log_dir: /var/log/myapp
myapp_port: 8080

Use in a playbook:

---
- name: Deploy application
  hosts: appservers
  become: true
  roles:
    - role: myapp
      vars:
        myapp_port: 9090

Collection Structure

# Initialize a collection
ansible-galaxy collection init myorg.mytools
myorg/mytools/
├── README.md
├── galaxy.yml            # Collection metadata
├── plugins/
│   ├── modules/          # Custom modules
│   ├── inventory/        # Inventory plugins
│   └── filter/           # Custom filters
├── roles/                # Roles within the collection
├── playbooks/            # Reusable playbooks
└── docs/

Common Collections

CollectionPurpose
ansible.builtinCore modules (included)
ansible.posixPOSIX systems (mount, sysctl, cron)
community.generalGeneral community modules
community.postgresqlPostgreSQL management
community.dockerDocker containers
community.vmwareVMware vSphere
amazon.awsAWS resources
azure.azcollectionAzure resources
google.cloudGCP resources
kubernetes.coreKubernetes/Helm
ansible.windowsWindows management
ansible.netcommonNetwork automation

Installation Paths

Default installation locations:

# Roles
~/.ansible/roles/                    # User roles
/etc/ansible/roles/                  # System roles
./roles/                             # Project roles (checked first)

# Collections
~/.ansible/collections/              # User collections
/usr/share/ansible/collections/      # System collections
./collections/                       # Project collections

Configure in ansible.cfg:

[defaults]
roles_path = ./roles:~/.ansible/roles:/etc/ansible/roles
collections_path = ./collections:~/.ansible/collections

Troubleshooting

"the role 'x' was not found"

Check installation path:

ansible-galaxy role list
# Verify the role is installed

# Install to project directory
ansible-galaxy role install geerlingguy.docker -p ./roles/

"Collection not found"

ansible-galaxy collection list
# Verify installed

# Install specific version
ansible-galaxy collection install community.general:9.0.0 --force

Galaxy Rate Limiting

# Use a Galaxy API token
ansible-galaxy role install geerlingguy.docker --token YOUR_TOKEN

# Or set in ansible.cfg
# [galaxy]
# server_list = galaxy
# [galaxy_server.galaxy]
# url = https://galaxy.ansible.com/
# token = YOUR_TOKEN

Conclusion

Ansible Galaxy saves hours of work by providing community roles and collections for common infrastructure tasks. Use requirements.yml to pin versions and ensure reproducible installs. Start with popular roles (geerlingguy's are excellent) and collections (community.general, ansible.posix). Create your own roles with ansible-galaxy role init to package reusable automation. Always pin versions in production to avoid surprise breaking changes.