Introduction

Ansible Galaxy is the package manager for Ansible content — install community roles and collections from galaxy.ansible.com, create your own, and share them. Collections bundle roles, modules, plugins, and playbooks into distributable packages.

Install a Role

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

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

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

# List installed roles
ansible-galaxy role list

Use in a playbook:

---
- hosts: webservers
  become: true
  roles:
    - geerlingguy.docker
    - geerlingguy.nginx

Install a Collection

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

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

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

# List installed collections
ansible-galaxy collection list

Requirements File

Define all dependencies in one file:

# 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/myorg/ansible-role-myapp.git
    name: myapp
    version: v2.0.0

collections:
  - name: community.general
    version: ">=9.0.0"
  - name: amazon.aws
    version: "7.0.0"
  - name: community.docker
  - name: ansible.posix
# Install everything
ansible-galaxy install -r requirements.yml

# Or separately
ansible-galaxy role install -r requirements.yml
ansible-galaxy collection install -r requirements.yml

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

Create a Role

# Scaffold a new role
ansible-galaxy role init my_role

# Creates:
my_role/
├── README.md
├── defaults/
│   └── main.yml        # Default variables (easily overridden)
├── files/              # Static files
├── handlers/
│   └── main.yml        # Handlers
├── meta/
│   └── main.yml        # Role metadata, dependencies
├── tasks/
│   └── main.yml        # Main task list
├── templates/          # Jinja2 templates
├── tests/
│   ├── inventory
│   └── test.yml
└── vars/
    └── main.yml        # Role variables (high precedence)

Minimal Role Example

# roles/myapp/tasks/main.yml
---
- name: Install packages
  ansible.builtin.apt:
    name: "{{ myapp_packages }}"
    state: present

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

- name: Ensure service running
  ansible.builtin.service:
    name: "{{ myapp_name }}"
    state: started
    enabled: true

# roles/myapp/defaults/main.yml
---
myapp_name: myapp
myapp_user: myapp
myapp_port: 8080
myapp_packages:
  - python3
  - python3-pip

# roles/myapp/handlers/main.yml
---
- name: Restart myapp
  ansible.builtin.service:
    name: "{{ myapp_name }}"
    state: restarted

# roles/myapp/meta/main.yml
---
dependencies:
  - role: geerlingguy.docker
    when: myapp_use_docker | default(false)

Create a Collection

# Scaffold a new collection
ansible-galaxy collection init myorg.mytools

# Creates:
myorg/mytools/
├── README.md
├── galaxy.yml           # Collection metadata
├── plugins/
│   ├── modules/         # Custom modules
│   ├── inventory/       # Inventory plugins
│   └── filter/          # Custom filters
├── roles/               # Bundled roles
├── playbooks/           # Reusable playbooks
└── docs/
# galaxy.yml
namespace: myorg
name: mytools
version: 1.0.0
readme: README.md
authors:
  - Your Name
description: Internal automation tools
license: GPL-3.0-or-later
dependencies:
  community.general: ">=9.0.0"
  ansible.posix: ">=1.5.0"
# Build collection
ansible-galaxy collection build

# Install locally
ansible-galaxy collection install myorg-mytools-1.0.0.tar.gz

# Publish to Galaxy
ansible-galaxy collection publish myorg-mytools-1.0.0.tar.gz --api-key YOUR_KEY

Install from Git

# requirements.yml — roles from Git
roles:
  - src: git+https://github.com/myorg/ansible-role-app.git
    name: myapp
    version: main

  - src: git@github.com:myorg/private-role.git
    name: private_role
    version: v1.2.0

# Collections from Git
collections:
  - name: https://github.com/myorg/ansible-collection.git
    type: git
    version: main

Install from Private Galaxy / Automation Hub

# ansible.cfg
[galaxy]
server_list = automation_hub, galaxy

[galaxy_server.automation_hub]
url = https://console.redhat.com/api/automation-hub/
auth_url = https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
token = YOUR_TOKEN

[galaxy_server.galaxy]
url = https://galaxy.ansible.com/

Project Structure

project/
├── ansible.cfg
├── requirements.yml        ← Dependencies
├── inventory/
├── group_vars/
├── playbooks/
│   └── site.yml
├── roles/
│   ├── requirements.yml    ← Role-only requirements
│   └── local_role/         ← Local roles
└── collections/
    └── requirements.yml    ← Collection-only requirements
CollectionPurpose
community.generalGeneral utilities, system modules
ansible.posixPOSIX system modules
amazon.awsAWS resources
azure.azcollectionAzure resources
google.cloudGCP resources
community.dockerDocker management
community.kubernetesKubernetes/K8s
community.mysqlMySQL management
community.postgresqlPostgreSQL management
ansible.netcommonNetwork automation base
cisco.iosCisco IOS devices

Troubleshooting

"Role not found"

Check the roles path:

# Show where Ansible looks for roles
ansible-config dump | grep ROLES_PATH

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

Version Conflicts

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

# Upgrade
ansible-galaxy collection install community.general --upgrade

"Collection not found" in Playbook

Use the FQCN (fully qualified collection name):

# WRONG
- docker_container:
    name: myapp

# RIGHT
- community.docker.docker_container:
    name: myapp

Conclusion

Ansible Galaxy manages your automation dependencies. Use requirements.yml to pin role and collection versions — install everything with ansible-galaxy install -r requirements.yml. Create roles with ansible-galaxy role init for reusable task bundles. Create collections with ansible-galaxy collection init for distributable packages of roles + modules + plugins. Always use FQCNs (community.general.timezone) in playbooks and pin versions in requirements files for reproducible automation.