pdeva
pdeva

Reputation: 45461

How to automatically install Ansible Galaxy roles?

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

Answers (15)

Venkat
Venkat

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

tholeb
tholeb

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

bviktor
bviktor

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

Chris F
Chris F

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

panticz
panticz

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

AJAX
AJAX

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

  1. On your gitlab account create a group where you put all your roles
  2. Go to settings/repository and add a token with read rights
  3. Copy the token-name:token an paste it in a requirements.yml file
- src: 'https://<token-name>:<token>@gitlab.com/ansible-cim/roles/instnginx.git'
  scm: 'git'
  version: 'v0.0.1'
  name: 'instnginx'
  1. Edit ansible.cfg if necessary to indicate where roles will be installed
[defaults]
roles_path=./roles
  1. Create folder ./roles if necessery
  2. Launch ansible-galaxy command
mkdir roles
ansible-galaxy install -r requirements.yml

Upvotes: 0

bbaassssiiee
bbaassssiiee

Reputation: 6782

If requirements.yml resides in the roles directory of your project, then Tower/AWX installs the roles automatically.

Upvotes: 0

TJVerne
TJVerne

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

Marco Ferrari
Marco Ferrari

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

Kieran Andrews
Kieran Andrews

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

staylorx
staylorx

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

dfarrell07
dfarrell07

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

udondan
udondan

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

Mxx
Mxx

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

Related Questions