How to automatically install Ansible Galaxy roles?

2020-02-02 03:55发布

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.

7条回答
贼婆χ
2楼-- · 2020-02-02 04:19

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

查看更多
家丑人穷心不美
3楼-- · 2020-02-02 04:20

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 
查看更多
欢心
4楼-- · 2020-02-02 04:26

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.

查看更多
迷人小祖宗
5楼-- · 2020-02-02 04:28

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.

查看更多
一纸荒年 Trace。
6楼-- · 2020-02-02 04:38

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.

查看更多
forever°为你锁心
7楼-- · 2020-02-02 04:38

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.

查看更多
登录 后发表回答