Automatic Ansible custom modules installation with Ansible Galaxy - ansible

Is there any nice way to use Ansible Galaxy order to install and enable Ansible (2.7.9) custom modules?
My requirement allows Ansible Galaxy to download the right Ansible role which embeds my custom module. Once ansible-galaxy install --roles-path ansible/roles/ -r roles/requirements.yml, I get the following structure (non-exhaustive):
├── ansible
│   ├── roles
│   │   ├── mymodule (being imported by Galaxy)
│   │   │   ├── library
│   │   │   │   └── mymodule.py
By looking this part of the documentation, it seems like my module is at the right place and does not require any further configuration: https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html?highlight=library#directory-layout
But when I found this part of the documentation I got confused. Is ANSIBLE_LIBRARY related to the custom modules?
DEFAULT_MODULE_PATH
Description: Colon separated paths in which Ansible will search for Modules.
Type: pathspec
Default: ~/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
Ini Section: defaults
Ini Key: library
Environment: ANSIBLE_LIBRARY
https://docs.ansible.com/ansible/latest/reference_appendices/config.html#default-module-path
When calling my module,
- name: Test of my Module
mymodule:
I get the following error:
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
I expected not to have to configure the ANSIBLE_LIBRARY and the module being automatically callable. Am I understanding correctly or should I also trick this var?

If your custom module is in a role, you need to include the role in your playbook, so at the very least:
---
- hosts: myhosts
roles:
- role: mymodule
tasks:
- name: Test of my Module
mymodule:

Related

golang unknown revision module/vX.Y.Z and importing package properly

I have a golang application structure like this:
.
├── calc
│   ├── go.mod
│   ├── main.go
│   └── Makefile
├── go.mod
├── LICENSE
├── num
│   ├── go.mod
│   └── num.go
└── README.md
Where calc is an "application" where I'm importing the num package to add 2 numbers.
calc/go.mod
go 1.15
require github.com/github_username/goapp/num v0.2.1
num/go.mod
module github.com/github_username/goapp/num/v0.2.1
go 1.15
go.mod
module github.com/github_username/goapp/v0.2.1
go 1.15
When in /calc, and I run go run main.go, I get the following:
go: github.com/github_username/goapp/num#v0.2.1: reading github.com/github_username/goapp/num/num/go.mod at revision num/v0.2.1: unknown revision num/v0.2.1
What am I doing wrong? The github repo has the annotated tags.
For further context, I'm mimicking a production setup where we have six different mini golang services in folders such as calc, calc2, etc. where each "calc" service has a go.mod file.
module github.com/github_username/goapp/num/v0.2.1
Is nonsense. The semver version tag "v0.2.1" does not belong into the module name.
(Note that for major versions > 1, e.g. 4.3.1, the major version becomes part of the name like in module github.com/user/proj/folder/v4).
And one more: There are no source code belonging to the root go.mod so this module makes no sense whatsoever.
You really should not make that many modules.
Are you working with private repositories?
if yes, then you need to configure OAuth authentication:
export GITHUB_TOKEN=MY_GITHUB_TOKEN
git config --global url."https://${GITHUB_TOKEN}:x-oauth-basic#github.com/".insteadOf "https://github.com/"
Now, if you don't have the necessity to use private repositories!
Turn your repositories to the public that will solve the problem too.

How do I run ansible-test on the root of my collection?

I'm currently developing my own Ansible collection and following the documentation. The directory structure looks like this:
~/.ansible/collections/gertvdijk/mycollection
├── galaxy.yml
├── plugins
│   └── lookup
│   └── mylookup.py
├── README.md
└── tests
└── unit
└── plugins
└── lookup
└── test_mylookup.py
The location ~/.ansible/collections/gertvdijk/mycollection is chosen for convenience so that it's found on the default search paths for collections (COLLECTIONS_PATHS).
The Ansible developer document section Testing collections mentions that I should use ansible-test command from the root of my collection with the given structure.
You must always execute ansible-test from the root directory of a collection.
However, that fails to me, with an error as if I should use this in a project already.
Even running --help fails with the current working directory error:
$ ansible-test --help
ERROR: The current working directory must be at or below:
- an Ansible collection: {...}/ansible_collections/{namespace}/{collection}/
Current working directory: /home/gert/.ansible/collections/gertvdijk/mycollection
Same thing happens by cloning an existing community collection (e.g. community.grafana). The GitHub CI steps include an installation in a ansible_collections/{namespace}/{collection} path (seen here).
Taking that as a work-around for now (I'd like to avoid that); move the repository of the collection to some path that includes /ansible_collections/gertvdijk/mycollection and then run it from there.
This can't be true, right, that the directory name two levels up make or break the ansible-test tool? What am I missing here?
TL;DR: The path for your home collection should be /home/gert/.ansible/collections/ansible_collections/gertvdijk/mycollection
The directories listed in COLLECTION_PATH are actually expected to contain a top level ansible_collections folder. This is linked to the ansible_collections convention used by e.g. module_utils as explained in the documentation
You can also observe how a blank folder gets structured by running e.g.
ansible-galaxy collection install -p /whatever community.grafana
In this case, you will end up with the folder /whatever/ansible_collections/community/grafana.
So your actual home folder collection path should be /home/gert/.ansible/collections/ansible_collections/gertvdijk/mycollection

Conditionally manage Helm chart dependencies without keeping the child charts inside 'charts' directory

I currently have 3 Helm repositories with the following structure:
repoA/
├── templates/
├── Chart.yaml
├── values.yaml
repoB/
├── templates/
├── Chart.yaml
├── values.yaml
masterRepo/
├── templates/
├── Chart.yaml
├── values.yaml
├── requirements.yaml
The requirements.yaml file from masterRepo is something like below:
dependencies:
- name: repoA
version: "1.0"
repository: "file://../repoA"
condition: repoA.enabled
- name: repoB
version: "1.0"
repository: "file://../repoB"
condition: repoB.enabled
I would like to only use masterRepo to deploy the dependent Helm charts.
I know I can manually put all the child repositories in the masterRepo/charts and it will work but I wanna keep these repositories independent so that other master-repositories can use any of
What to do to make parent Helm chart detect all the required Helm charts and install them conditionally (based on repoX.enabled variable) without keeping the dependent repositories inside the charts directory of the Master-helm-chart?
If you have multiple Helm charts at different locations in the system, you can create dependencies without changing their location.
With the structure specified in the question, we can add dependencies in requirements.yaml (for Helm version: 2.x.x) or Chart.yaml (for Helm version:3.x.x). I am currently using Helm v2.16.1.
Now simply run helm dependency update or helm dep up from inside the masterRepo directory and a charts directory gets created. Now the updated structure of masterRepo looks like:
masterRepo/
├── charts/
└── chartA-1.tgz
└── chartB-1.tgz
├── templates/
├── Chart.yaml
├── requirements.lock
├── requirements.yaml
├── values.yaml
The new files/directories added are:
ChartA-1.tgz and ChartB-1.tgz TAR Archive files which are nothing but zipped chartA and chartB charts.
requirements.lock: Used to rebuild the charts/ directory. Read more about this file in this SO post.
To install the child charts conditionally, you can the following the values.yaml file of the masterRepo:
repoA:
enabled: True
repoB:
enabled: True
Now a simple helm install command from inside the masterRepo will deploy masterRepo as well as it's dependencies (chartA and chartB).
Hope this helps. Happy Helming!

Ruby Uninitialized Constant Error when Inheriting in Chef

In my LWRP extending a supermarket cookbook, I got the following working.
module PIWebsphereCookBook
class WebsphereJbdc < WebsphereCookBook::WebsphereBase
Whereas when I introduced my own class in between these 2, I am getting the 'Unitialized Constant Error'
require_relative './pi_websphere_base'
module PIWebsphereCookBook
class WebsphereJbdc < PIWebsphereBase
The base class I am trying to extend is as shown below:
module PIWebsphereCookBook
class PIWebsphereBase < WebsphereCookbook::WebsphereBase
I see from the logs that the referenced class/file is being loaded
[2017-06-23T18:37:28-04:00] DEBUG: Loading cookbook pi_websphere's resources from /var/chef/cache/cookbooks/pi_websphere/resources/pi_websphere_base.rb
[2017-06-23T18:37:28-04:00] DEBUG: Loaded contents of /var/chef/cache/cookbooks/pi_websphere/resources/pi_websphere_base.rb into resource pi_websphere_pi_websphere_base (Custom resource pi_websphere_pi_websphere_base from cookbook pi_websphere)
[2017-06-23T18:37:28-04:00] DEBUG: Loading cookbook pi_websphere's resources from /var/chef/cache/cookbooks/pi_websphere/resources/websphere_j2c.rb
[2017-06-23T18:37:28-04:00] DEBUG: Loaded contents of /var/chef/cache/cookbooks/pi_websphere/resources/websphere_j2c.rb into resource pi_websphere_websphere_j2c (Custom resource pi_websphere_websphere_j2c from cookbook pi_websphere)
[2017-06-23T18:37:28-04:00] DEBUG: Loading cookbook pi_websphere's resources from /var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb
[2017-06-23T18:37:28-04:00] DEBUG: Filtered backtrace of compile error: /var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:3:in `<module:PIWebsphereCookBook>',/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:2:in `class_from_file'
[2017-06-23T18:37:28-04:00] DEBUG: Backtrace entry for compile error: '/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:3:in `<module:PIWebsphereCookBook>''
[2017-06-23T18:37:28-04:00] DEBUG: Line number of compile error: '3'
Recipe Compile Error in
/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb
NameError
---------
uninitialized constant #
<Class:0x000000052796d8>::PIWebsphereCookBook::PIWebsphereBase
Cookbook Trace:
---------------
/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:3:in ` <module:PIWebsphereCookBook>'
/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:2:in ` class_from_file'
Relevant File Content:
----------------------
/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:
1: require_relative './pi_websphere_base'
2: module PIWebsphereCookBook
3>> class WebsphereJbdc < PIWebsphereBase
4: require_relative 'helper'
5:
The folder structure is given below
[root#localhost pi_websphere]# tree
.
├── attributes
│   └── default.rb
├── Gemfile
├── jaas_auth.py
├── libraries
│   ├── abc.rb
│   ├── artifactory_helper.rb
│    ├── pi_websphere_base.rb
│   └── websphere_base.rb
├── metadata.rb
├── README.md
├── resources
│   ├── artifactory_client.rb
│   ├── helper.rb
│   ├── websphere_j2c.rb
│   ├── websphere_jdbc.rb
You need to make sure the file containing PIWebsphereBase is loaded first. Normally cookbook library files are loaded in ASCII-betical order, but you can force things a little more with the require_relative you have there but is commented out. You probably want require_relative './pi_websphere_base' or something like that, or tweak the filenames.

How can I store ansible playbooks in different directories but still be able to call them?

It seems that ansible assumes that the ansible.cfg file exists in the current working directory so when you try to call a playbook that exists in a subdirectory it will fail to load the roles and other stuff.
Is it possible to store playbook in different directories?
Please note that the ansible.cfg is part of the source code.
Per the documentation, Ansible will look for the configuration file in the following order:
ANSIBLE_CONFIG (an environment variable)
ansible.cfg (in the current directory)
.ansible.cfg (in the home directory)
/etc/ansible/ansible.cfg
So if you'd like to call playbooks from alternate directories, you can pass along ANSIBLE_CONFIG pointing at the appropriate ansible.cfg.
I was facing the same problem. I wanted to putt all the playbooks in a separate directory instead of having them all flying around in my base directory.
My base directory is under git control an it contains a local ansible.cfg file with the following content:
[defaults]
inventory=hosts
roles_path=roles
By setting roles_path ansible with look for the roles directory in the base directory instead of the subdirectory of your playbooks.
Be aware that if you have another directory with files you're referencing in your playbooks, you have to qualify this as followed:
- name: copy nagios config files
copy:
src: ../files/nagios3/config/
dest: /etc/nagios3/conf.d/
owner: root
group: root
notify: reload nagios
In this case the playbook is located in a playbooks subdirectoy at the same level as the files directory.
Just like that:
.
├── README
├── ansible.cfg
├── files
│   └── ...
├── host_vars
│   └── ...
├── hosts
├── playbooks
│   └── ...
├── roles
│   └── ...
└── templates
└── ...

Resources