Reputation: 45461
All my Ansible playbooks/roles are checked in to my git repo.
However, for Ansible Galaxy roles I always have to explicitly download them one by one on every machine I want to run Ansible from.
It's even tough to know in advance exactly which Ansible Galaxy roles are needed until Ansible complains about a missing role at runtime.
How is one supposed to manage the Ansible Galaxy role dependencies? I would like to either have them checked into my git repo along with the rest of my ansible code or have them automatically be identified and downloaded when I run Ansible on a new machine.
Upvotes: 170
Views: 126092
Reputation: 21
By using below command we can achieve
If you want install a specific role below command
ansible-galaxy role install namespace.role_name
If you want install multiple roles by below command
ansible-galaxy role install -r requirements.yml
Upvotes: 1
Reputation: 170
Based on @staylorx answer, you can create a pre-task like so:
- name: Install requirements
delegate_to: localhost
ansible.builtin.command: ansible-galaxy install -r {{ role_path }}/requirements.yml
that points to your requirements.yml
For example, your playbook will probably look like this:
---
- name: Deploy
hosts: all
gather_facts: true
# ...
collections:
# All the collections you'll need
pre_tasks:
- name: Install requirements
delegate_to: localhost
ansible.builtin.command: ansible-galaxy install -r {{ role_path }}/requirements.yml
# Other tasks that you run BEFORE the roles
roles:
- { role: "roleX", tags: "roleX" }
# your other roles
post_tasks:
# other tasks that you run AFTER the roles
Refs:
Upvotes: 1
Reputation: 1526
Simply put: you can't. At best you can add a separate role to do the installs, but it will still fail if you try to include a Galaxy role in your playbook. So there's simply no other way than to install it manually. Yes, it is ridiculous, like many other things in Ansible.
Upvotes: 3
Reputation: 16673
There is no mechanism to automatically download a playbook's needed roles. As others have suggested, using a requirements.yml
file is one way, and maybe the best way, to do this.
However, you can also use a role's meta/main.yml
file to specify it's dependencies. See the Roles documentation page. You can use this syntax for if you're using a private repo for example.
dependencies:
- name: java
src: ssh://git@myServer/myWorkspace/myRole.git
scm: git
version: master
So you can define a requirements.yml
file to download myRole
, and then it will download any roles it needs, and they can in turn download any roles they need through their meta/main.yml
files. This is a lot more work that having a requirements.yml
file IMO.
Upvotes: 1
Reputation: 2315
Exaple HowTo install a Ansible Galaxy role in playbook:
- name: Install role from Ansible Galaxy
local_action: command /usr/bin/ansible-galaxy install <GALAXY_PACKAGE_NAME>
Upvotes: 1
Reputation: 1
I use Crono's method in AWX but also on my local ansible controller.
It works well but somehow messes with the path where roles are eventually downloaded to.
My Git project is called 'roles' and I add it to requirements.yml:
- src: "git+https://<token_name>:<token>@gitlab.mydomain.com/mygroup/ansible/roles.git"
When I run
ansible-galaxy install -r requirements.yml
I get this folder structure in my roles directory after sync:
├── roles
│ └── roles
│ └── My_Role
│ ├── tasks
│ │ └── main.yml
This forces me to include my roles like this in the playbook:
hosts: [all]
roles:
- roles/roles/My_Role
Is there any way to sync the roles from git without the root folder?? You can do this with git via:
git clone "https://<token_name>:<token>@gitlab.mydomain.com/mygroup/ansible/roles.git ."
but the dot convention does not work inside the requirements.yml
file.
Any ideas will be much appreciated.
Upvotes: 0
Reputation: 9
- src: 'https://<token-name>:<token>@gitlab.com/ansible-cim/roles/instnginx.git'
scm: 'git'
version: 'v0.0.1'
name: 'instnginx'
[defaults]
roles_path=./roles
mkdir roles
ansible-galaxy install -r requirements.yml
Upvotes: 0
Reputation: 6782
If requirements.yml resides in the roles directory of your project, then Tower/AWX installs the roles automatically.
Upvotes: 0
Reputation: 75
Here, my requirements are on the role and used in install.yml
main.yml
# tasks file for MY_ROLE
- name: Install requirements
local_action: command ansible-galaxy install -r {{ role_path }}/requirements.yml -p /etc/ansible/roles
- include_tasks: install.yml
.
├── playbook.yml
├── inventory
├── roles
│ └── My_Role
│ ├── tasks
│ │ └── main.yml
│ │ └── install.yml
│ └── requirements.yml
Upvotes: 3
Reputation: 5253
You could use an Ansible role to install the needed roles using the command module.
Here is a very basic example that runs ansible-galaxy install
:
- name: Install roles from Ansible Galaxy
command: ansible-galaxy install {{ item.item }}
with_items:
- "{{ ansible_roles_list }}"
The ansible_roles_list
may be supplied as a variable or as a role parameter.
If you do this in a role, it has to be applied before any other roles that you want to install using it, in a separate playbook. This is because Ansible checks the if all the roles are available before running the playbook where you reference them.
Upvotes: 13
Reputation: 5885
As suggested, you can use ansible galaxy for this need.
Ansible has a feature where you can create a requirements.yml
file that lists all of your roles. You can find out about that here: http://docs.ansible.com/ansible/latest/galaxy.html#installing-multiple-roles-from-a-file
For example (requirements.yml):
- src: yatesr.timezone
You then run ansible-galaxy install -r requirements.yml
on this file to download all of the roles listed there.
If you would like to further automate it then, you can create a simple shell script that will run the two commands.
For example (ansible.sh):
./ansible.sh
ansible-galaxy install -r requirements.yml
ansible-playbook playbook.yml -i inventory
Upvotes: 56
Reputation: 1240
I often find myself installing installing a Java JDK. Using a role makes that touch easier. I've tried a couple of different ways (including lots of .gitmodules and submodule... I have to use multiple git systems for work and all it gets ugly). My largest requirement is that I not check role code into my playbook project, mostly so I can keep everything in one place.
The contents of my 'requirements.yml' file:
- src: https://github.com/staylorx/ansible-role-wls-prep.git
version: master
name: staylorx.wls-prep
- src: https://my-work-git-extravaganza.com
version: 2.x
name: coolplace.niftyrole
#From Ansible Galaxy
- src: staylorx.oracle-jdk
I run a separate playbook, install-roles.yml:
---
- hosts: localhost
tasks:
- file:
path: roles
state: absent
- local_action:
command ansible-galaxy install -r requirements.yml --roles-path roles
- lineinfile:
dest: .gitignore
regexp: '^\/roles$'
line: '/roles'
state: present
I run this first playbook, then I run my roles in any playbook normally. For me the secret is to ensure it's ignored by git so I don't check the roles in by mistake. Also since I wipe out the folder every time, I ensure I don't need to force or ignore errors.
Upvotes: 20
Reputation: 3018
You should use a requirements.yml
file for this use-case. Describe the roles you require, using any of a variety of install methods:
# Install a role from the Ansible Galaxy
- src: dfarrell07.opendaylight
# Install a role from GitHub
- name: opendaylight
src: https://github.com/dfarrell07/ansible-opendaylight
# Install a role from a specific git branch
- name: opendaylight
src: https://github.com/dfarrell07/ansible-opendaylight
version: origin/master
# Install a role at a specific tag from GitHub
- name: opendaylight
src: https://github.com/dfarrell07/ansible-opendaylight
version: 1.0.0
# Install a role at a specific commit from GitHub
- name: opendaylight
src: https://github.com/dfarrell07/ansible-opendaylight
version: <commit hash>
Then install them:
ansible-galaxy install -r requirements.yml
Here's a working example (installing OpenDaylight using Ansible as a Vagrant provisioner). See the relevant Ansible docs for more info.
Upvotes: 194
Reputation: 59989
Another solution is to use git submodules. After all, Ansible Galaxy only is a directory of github repositories...
I use this command to automatically add any Galaxy role as a submodule:
ansible-galaxy info <package> | grep -A 1 github_repo | tr '\n' ' ' | sed -e "s/.*github_repo: \([^[:space:]]*\)[^\w]*github_user: \([^[:space:]]*\)[[:space:]]*/git submodule add git:\/\/github.com\/\2\/\1.git roles\/\2.\1/g" | sh
Commit the changes then to your git repo. When you clone your repo in future make sure to clone it with submodules, e.g. git clone ... --recursive
An advantage of this is, a git submodule is always referencing a specific version (git commit-hash). This will prevent you from running untested updates in your productive environment. A new version of a Galaxy role could have bugs or work completely different than before. With a git submodule you decide if and when you update a role to the new version.
Also, you won't have to additionally take care of blacklisting galaxy roles in your .gitignore
to prevent committing their code to your repository.
Upvotes: 7
Reputation: 9346
At this point in time, as far as I know there's no automatic way to download roles at runtime. Your best bet is to either commit them into your own repo or have a proper documentation listing all the requirements. You could even create a pre-flight playbook that installs your roles. :)
Upvotes: 3