Is there a way to use galaxy roles without downloading them? - ansible

I'm running ansible within terraform.
I downloaded a galaxy role using:
ansible-galaxy install <role>
This downloaded it to my ~/.ansible/roles directory.
But when I referenced the role name in my ansible playbook that I use with terraform, it couldn't find it.
So instead I specified a directory like so:
ansible-galaxy install --roles-path . <role>
While this now works, it's mixed in with all my other scripts that are under source control.
I'm wondering if there's a way to use a galaxy role without actually downloading it? Or if there's a way to specify in my ansible playbook where to look for additional roles besides my roles?

Since Ansible only knows how to retrieve roles from the local filesystem, you must download roles before you can use them.
You can tell Ansible where to look for roles by setting the ANSIBLE_ROLES_PATH environment variable, or by setting roles_path in your ansible.cfg. See the documentation for details.

Related

how to not display skipped hosts/tasks?

I have many playbooks and I don't have access the where Ansible is installed. I can write my playbooks locally on my laptop then I push them to a repo and I can run them via Jenkins. I can't control or change e.g. ansible.cfg or so. Is there a way to manipulate the ansible default stdout callback plugin per playbook without accessing the ansible host itself?
Actually it is, you can use Environmental variable for this: check documentation
ANSIBLE_DISPLAY_SKIPPED_HOSTS=yes ansible-playbook main.yml
But for obvious reasons (It's deprecated) it's better to use the ansible.cfg option for this.
[defaults]
display_skipped_hosts = False

How to specify dependecies to Ansible Galaxy roles from other roles?

I've specified dependency for my role by declaring it inside meta/main.yml.
---
dependencies:
- role: angstwad.docker_ubuntu
src: https://github.com/angstwad/docker.ubuntu
scm: git
version: v2.3.0
However when I try to execute Ansible playbook I'm seeing error message:
ERROR! the role 'angstwad.docker_ubuntu' was not found in /home/.../ansible/roles:/etc/ansible/roles:/home/.../ansible/roles:/home/.../ansible
The error appears to have been in '/home/.../roles/docker-node/meta/main.yml': line 5, column 5, but may be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- role: angstwad.docker_ubuntu
^ here
From the error message I conclude that external role angstwad.docker_ubuntu hasn't be imported, even if it has been explicitly mentioned in docker-node/meta/main.yml.
Can I specify external dependencies from Ansible Galaxy even if my role itself has not been uploaded to Ansible Galaxy?
Or do I need to explicitly import them using ansible-galaxy?
From Ansible documentation:
Roles can also be dependent on other roles, and when you install a
role that has dependencies, those dependenices will automatically be
installed.
You specify role dependencies in the meta/main.yml file by providing a
list of roles. If the source of a role is Galaxy, you can simply
specify the role in the format username.role_name. The more complex
format used in requirements.yml is also supported, allowing you to
provide src, scm, version and name.
By following suggestions from another SO question (How to automatically install Ansible Galaxy roles?) it sounds like downloading external dependencies needs to be done explicitly either manually or with workaround.
If the role that has this dependency is itself being installed via ansible-galaxy, then revise meta/main.yml to look like this:
---
dependencies:
- src: https://github.com/angstwad/docker.ubuntu.git
scm: git
version: v2.3.0
Thus, when installing the primary role the docker.ubuntu role will automatically be installed in ~/.ansible/roles/docker.ubuntu and it will run when the playbook is executed.
If the role that has this dependency will NOT be installed via ansible-galaxy, that is, if the dependency is the only thing being installed via the ansible-galaxy command, then docker.ubuntu will have to be installed separately, e.g.
ansible-galaxy install git+https://github.com/angstwad/docker.ubuntu.git
or
ansible-galaxy install git+https://github.com/angstwad/docker.ubuntu.git -p /path_to/my_playbook/roles
This will place the role in your search path (again, ~/.ansible/roles/docker.ubuntu if not specified via -p). In this scenario, revise meta/main.yml to this:
---
dependencies:
- role: docker.ubuntu
Note that when pulling your role from github, it lands as docker.ubuntu vs docker_ubuntu. See https://galaxy.ansible.com/docs/using/installing.html#dependencies for more. Hope this helps.
As per documentation you linked, you see:
When dependencies are encountered by ansible-galaxy, it will automatically install each dependency to the roles_path.
Downloading of dependencies is handled by ansible-galaxy only, the src meta information doesn't affect ansible-playbook, which just looks inside your role directory and if it don't see a corresponding folder - it fails. As in answer in question you linked, you can indeed create a first task, or include in you playbook to run ansible galaxy before each start.

Always run ansible role before other role

I'm trying to find my way out of a dependency thicket. I'm using Ansible 1.9.2.
In a single playbook, I want to be able to install a Galaxy role (in the event, the Datadog.datadog role) and configure it. But Ansible always barfs; since the Datadog.datadog role doesn't exist until another role that I wrote installs the Galaxy role, it won't execute. This is how I'd really like it to be, cutting out the other roles that my playbook uses:
- hosts: all
roles:
- install_datadog
- (some other roles...)
- { role: Datadog.datadog, sudo: true }
vars:
datadog_api_key: "somekey"
I have tried all of the following, and none of them work for installing the Ansible Galaxy Datadog.datadog role first:
Having an earlier block in the same playbook that runs my install_datadog role.
Using an 'include' statement earlier in the playbook that includes the install_datadog role's main.yml.
Creating a pre_task statement in the above playbook.
Defining a role dependency doesn't make sense, because Datadog.datadog doesn't exist yet, so I can't define any dependencies in it. There is always an error akin to this:
ERROR: cannot find role in /etc/ansible/roles/Datadog.datadog
The only thing I can get to work is executing the install_datadog role in a prior run. This is not a great solution, as previously one playbook that had many execution blocks and role invocations configured our whole environment; this would require the execution of two playbooks in a specific order, which is highly inelegant.
So in a single run, how do I resolve a Galaxy role that won't exist until an earlier role has run to install it?
Make sure that your roles_path is correct. The roles_path variable in ansible.cfg specifies where ansible will look for roles, and the --roles-path option to ansible-galaxy will specify where the datadog role gets installed.
For example, my install task looks like this:
ansible-galaxy install Datadog.datadog --roles-path=/usr/home/vagrant
and in my ansible.cfg file I have this line:
roles_path = /vagrant/ansible/roles:/usr/home/vagrant

Run tasks in ansible before pre provisioning

I have a set of taks in my playbook that I would like to run before ansible checks to see if roles exist. (One installs roles from galaxy and github) Right now, it appears, that ansible checks if all of the roles referenced exist prior to running ANY tasks because I get fatal errors saying those roles don't cannot be found. Can I define a task that can be run before this pre-provisioning? I would like to do this via ansible and not have to put it in a bash script that runs before my playbook.
It would be a great way to automate downloading Galaxy dependencies and ensuring the latest/correct version of all roles is installed. Unfortunately this is not possible.
I tried this with
pre_tasks
playbook-includes
conditional playbook-includes
But it's all the same. The playbook is first completely parsed and resolved (includes, roles) before the first task is executed.

How to keep local roles separated from the ones loaded from ansible-galaxy?

I observed that roles downloaded from galaxy get installed inside the roles/ directory, where we already have our in-house ones, making quite hard to distiguish between external ones and internal ones.
Is there a way to keep them in separated directories, so we can avoid confusions?
In most cases I would expect to have a script that is updating the galaxy ones and that we would not modify them internally.
I think there is no standard way of doing this but you can use Ansibles behavior to your advantage.
Ansible searches in two locations for roles:
In the roles directory relative to your playbook
The path you configured in your ansible.cfg
What you now need to do depends on where you actually store you roles. We are storing our roles relative to our playbooks, so everything is in the same git repo.
Now you could define in your ansible.cfg to look for roles in an additional folder:
roles_path=./galaxy_roles
ansible-galaxy will install roles by default into the first found path of roles_path, so make sure to add the galaxy folder as very first if you have multiple role paths. You do not need to add the roles folder explicitly. Ansible will by default always search for roles inside the ./roles folder relative to the playbook.
Alternatively you can also instruct galaxy to install to a different location:
ansible-galaxy install --roles-path=./galaxy_roles foo
The #udonhan inheritance answer could be not enough if you have internal/custom roles that are not always relative to a playbook, I mean global roles.
You can manage multiple roles path in ansible.cfg file, so you can define an ansible.cfg file in your project path with:
[defaults]
roles_path = ./roles:./roles_internal
The "./roles" path can be used for ansible-galaxy roles, and the "./roles_internal" can be used for your internal/custom roles
Now when you execute
ansible-galaxy install -r requeriments.yml
Galaxy roles are installed in "./roles" by default
NOTE: You must be sure that ANSIBLE_ROLES_PATH env variable is not set or it will override the ansible.cfg settings. For testing:
unset ANSIBLE_ROLES_PATH

Resources