Can I add roles in a private git repo as a meta/dependancy in Ansible? - ansible

I have a bunch of Ansible roles that I'd like to reuse. They are each kept in a repo in a private BitBucket.
I want to add projects that are hosted in Git as meta/dependencies for my the roles I'm working on but I can't quite figure out the syntax is.
In this non-working example, a role requires another role to be deployed first with parameters prior to running.
FYI, The remote role "acm_layout" is intended to create a standard directory layout for the server, so that my role can run knowing that all of the standard directories already exist.
---
dependencies:
- { role: project_keys } # Works fine, just reuses a local role
- name: acm_layout # Doesn't work, but this is what I want to fix
src: ssh://git#bigcompany.com/acm/acm_layout.git
scm: git
version: feature/initialize
application_storage_dir: "{{base_storage_dir}}"
application_data_dir: "{{app_data_dir}}"
When I runt this I get the following error:
ERROR! the role 'acm_layout' was not found in [lots of paths deleted]
The error appears to have been in '/home/zs5fgzg/_tmp/horizon_deployment_scf/ansible/roles/horizon_layout/meta/main.yaml': line 4, column 6, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- { role: horizon_keys }
- src: ssh://git#bigcompany.com:7999/acm/acm_layout.git
^ here
So what's the correct way to do this?

Yes, you can use ansible-galaxy install with requirements.yml option to get roles remotely. Create requirements.yml as follows:
https://github.com/avinash6784/elk-stack/blob/master/requirements.yml
And run the following command:
$ ansible-galaxy install -r requirements.yml -p roles/
For more info on how to get roles using ansible-galaxy please visit
http://docs.ansible.com/ansible/latest/galaxy.html

Related

ERROR! couldn't resolve module/action . This often indicates a misspelling, missing collection, or incorrect module path

I've got an Ansible Collections in my Ansible playbook as follows:
- name: Create a profile for the user
community.windows.win_user_profile:
username: test
name: test
state: present
and the collection is installed via
ansible-galaxy collection install ansible.windows
so I can see it at ~/.ansible/collections.
However I keep getting:
ERROR! couldn't resolve module/action 'community.windows.win_user_profile'. This often indicates a misspelling, missing collection, or incorrect module path.
I've also copied it alongside the playbook just in case but still get the same error message.
Any suggestions?
I got the same error with Ansible 2.9 on Ubuntu 20.04 after install community.general. The solution in this case was installing ansible.posix
ansible-galaxy collection install ansible.posix
as this contains the mount module https://docs.ansible.com/ansible/latest/collections/ansible/posix/mount_module.html
There are two Windows collections: community and Supported. I know that's confusing :(
Looks like you've installed ansible.windows, though you are using community.windows
The fix is:
ansible-galaxy collection install community.windows
ansible 2.9 uses collections different.
One way is to add them to the top:
---
- hosts: all
collections:
- community.windows
and then later use:
- name: Create a profile for the user
win_user_profile:
username: test
name: test
state: present
for reference:
Use Ansible Collections
collections are backwardcompatible
Dirty:
dont do this, but it works.
ansible-config dump |grep DEFAULT_MODULE_PATH
and copy them there (example replace path and name)...
cp -p ~/.ansible/collections/ansible_collections/community/general/plugins/modules/system/sudoers.py ./library/
Adding below details to your question would be helpful
Ansible host operating system
Ansible version
I guess, this is error is specific to ansible version. I guess you are using ansible 2.9 version or lower version. whereas, Installing collections with ansible-galaxy is only supported in ansible 2.9+.
Reference link : https://galaxy.ansible.com/ansible/windows ( look into 'Note' section )
You can upgrade your ansible version and give a try.
Reference link : https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#upgrading-from-2-9-or-earlier-to-2-10

Specify Collection dependency for Molecule

Molecule is informed to download role dependencies from Ansible Galaxy via
dependency:
name: galaxy
options:
role-file: requirements.yml
However, there doesn't appear to be any documentation on how Molecule can be informed to download Collections. https://molecule.readthedocs.io/en/stable/configuration.html#ansible-galaxy does not list a collections option and I don't see an open feature request on https://github.com/ansible/molecule for this.
Asking here in case this is a solved issue for Molecule, otherwise I suppose this would be a feature request on the Molecule github repo. How can I inform Molecule that it needs to download a Collection for a ansible-galaxy dependency?
My requirements.yml file looks like this:
---
roles:
- src: gantsign.visual-studio-code
- src: artis3n.bitwarden_app
collections:
- name: artis3n.github
This format is supported by Ansible at https://docs.ansible.com/ansible/devel/user_guide/collections_using.html#install-multiple-collections-with-a-requirements-file.
The documentation now covers collections as well since #2609. However, if you look at this pull request you can see it shouldn't have passed because the tests fail. It makes sense now that I was unable to get a working solution on my host more than 8 days ago; I notice the last merge after tests passed was 8 days ago.
I don't think this latest merge has been released yet, but I believe there is a workaround.
The issue I filed against Molecule has been completed, so this functionality is now present in Molecule as of version 3.0.3.

Have ansible role retrieve its files from external location as part of its own role

So one thing we've encountered in our project is that we do not want to store our large files in our git repo for our ansible roles because it slows down cloning (and git limits files to 100 mb anyways).
What we've done is store our files in a separate internal location, where our files can sit statically and have no size restrictions. Our roles are written so that they first pull these static files to their local files folder and then continue like normal.
i.e.
roles/foo/tasks/main.yml
- name: Create role's files directory
file:
path: "{{roles_files_directory}}"
state: directory
- name: Copy static foo to local
get_url:
url: "{{foo_static_gz}}"
dest: "{{roles_files_directory}}/{{foo_gz}}"
#....Do rest of the tasks...
roles/foo/vars/main.yml
roles_files_directory: "/some/path/roles/foo/files"
foo_static_gz: "https://internal.foo.tar.gz"
foo_gz: "foo.tar.gz"
The main thing I don't find really sound is the hard coded path to the role's files directory. I preferably would like to dynamically look up the path when running ansible, but I haven't been able to find documentation on that. The issue can arise because different users may check roles to a different root paths. Does anyone know how to dynamically know the role path, or have some other pattern that solves the overall problem?
Edit:
I discovered there's actually a {{playbook_dir}} variable that would return "/some/path", which might be dynamic enough in this case. Still isn't safe against the situation where the role name might change, but that's a way rarer occurrence and can be handled through version control.
What about passing values from the command line?
---
- hosts: '{{ hosts }}'
remote_user: '{{ user }}'
tasks:
- ...
ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"
http://docs.ansible.com/playbooks_variables.html#passing-variables-on-the-command-line
I just want to add another possible solution: you can try to add custom "facter".
Here is a link to official documentation: http://docs.ansible.com/setup_module.html
And I found this article that might be useful: http://serverascode.com/2015/01/27/ansible-custom-facts.html

Sharing Ansible roles

I have packages of Ansible roles that I would like to import into a project.
If I organise them by subdirectory I run into problems relating to dependency relative paths
i.e the shared role needs to know its relative location of where it would be installed if it uses meta dependencies
I would like to be able to just reference everything to the directory the playbook is being run from though this doesn't work
roles/roleA/meta
---
dependencies:
- { role: "{{ playbook_dir }}/roles/shared_roles/roleB"}
roles/shared_roles/roleB
...
I've tried multiple options and running out of ideas.
I looked into roles-path http://docs.ansible.com/intro_configuration.html#roles-path
Though I don't really want to have to uniquely name all roles as they ought to be namespaced / grouped.
Thanks
You could basically use ansible-galaxy to install the roles within ~/.ansible/roles/ path.
The path of .ansible in my macOS machine is in: ~/.ansible/roles/
All you need to do is just create a requirements.yml file which looks something like this:
- src: git+https://<githubURL-Master-role>.git
scm: git
name: Master-role
- src: git+https://<githubURL-dependent1-role>.git
scm: git
name: dependent1-role
- src: git+https://<githubURL-dependent2-role>.git
scm: git
name: dependent2-role
Run this command to install your roles in ~/.ansible/roles/ path:
sudo ansible-galaxy -vvv -r install requirements.yml
This will basically set your roles in the ~/.ansible/roles/ path. To understand it better please follow this documentation https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html.
and then, like you have already mentioned, you should add all the dependent roles in your ##path/master-role/meta/main.yml file even before executing the anisble-galaxy command, in-order to execute the dependent roles before the master-role, when you run your master-role playbook.
The ##path/master-role/meta/main.yml file looks something like this:
galaxy_info:
author: Jithendra
description: blah...blah...blah
min_ansible_version: 1.2
galaxy_tags:'[]'
dependencies:
- { role: 'Master-role, when: blah == "true"'} #when condition is optional
- { role: 'dependent1-role, when blah == "false"'}
- { role: 'dependent2-role, when blah == "false"'}
Solved it by enforcing that all shared modules reference the name of the shared directory in all dependencies.
I wanted to leave this up to the calling project and hoped that dependencies would be relative to the role directory.
The solution works though and provides namespacing so I can include multiple roles with the same name as long as they are in separate directories.
I now have a project that includes 3 separate packages of roles
PLAY RECAP ********************************************************************
staging : ok=214 changed=5 unreachable=0 failed=0
Its all built using Maven, each shared group being a maven dependency. If anybody reads this and it helps i'll share the structure / poms etc.

Keep Ansible DRY: How to avoid repeating variables?

Recently just started using Ansible and I have run into a problem. In one of my YAML structures I have defined something like this:
---
# file: main.yml
#
# Jenkins variables for installation and configuration
jenkins:
debian:
# Debian repository containing Jenkins and the associated key for accessing the repository
repo: 'deb http://pkg.jenkins-ci.org/debian binary/'
repo_key: 'http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key'
# Dependencies needed for Jenkins to run properly
dependencies:
- 'openjdk-7-jdk'
- 'git-core'
- 'curl'
port: 8080
# Installation directory
home: '/opt/jenkins'
# Path to the location of the main Jenkins-cli binary
bin_path: '{{jenkins.home}}/jenkins-cli.jar'
# Path to the location of the Jenkins updates file
updates_path: '{{jenkins.home}}/updates_jenkins.json'
Ansible gives me an error like this from a specific task:
"recursive loop detected in template string:
{{jenkins.home}}/updates_jenkins.json"
I've narrowed it down to the problem being with the fact bin_path and updates_path both refer to 'home'. Is there a way around this? It kind of sucks that I would need to define '/opt/jenkins' multiple times.
As far as I know that this is a limitation of jinja2 variables. it was working with the old ${} and broke since 1.4. I am not sure if they fixed that in 1.5.
My temp solution would be removing home from the "jenkins"
---
# file: main.yml
#
# Jenkins variables for installation and configuration
# Installation directory
jenkins_home: '/opt/jenkins'
jenkins:
debian:
# Debian repository containing Jenkins and the associated key for accessing the repository
repo: 'deb http://pkg.jenkins-ci.org/debian binary/'
repo_key: 'http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key'
# Dependencies needed for Jenkins to run properly
dependencies:
- 'openjdk-7-jdk'
- 'git-core'
- 'curl'
port: 8080
# Path to the location of the main Jenkins-cli binary
bin_path: '{{jenkins_home}}/jenkins-cli.jar'
# Path to the location of the Jenkins updates file
updates_path: '{{jenkins_home}}/updates_jenkins.json'
This should do it:
bin_path: "{{ jenkins['home'] }}/jenkins-cli.jar"

Resources