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
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. :)
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.
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
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.
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.
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.