Closed emmetog closed 3 years ago
Good question!
Modules are designed to each handle one, related task. Many times, that means one module handles one program. For example, one module might handle firewall rules, another may update the system, another may configure a database, etc.
As such, I would recommend only having a single module per task. If you create too many modules executing similar tasks, it can get confusing and/or hard to debug or update in the future.
Within your module directory, however, is where you can differentiate between systems. Remember, the modules directory only requires you to supply an apply
file, and optionally a variables
file. Other than those two files, you can add any other files or directories you'd like. Therefore, it's perfectly reasonable to create multiple directories within the module, each containing files to be executed depending on the OS version. To specify which files to execute, you could write a simple if-statement in your main apply
file, which could look something like this:
# Main apply file:
if [ "$(lsb_release -a | grep Release: | awk '{print $2}')" == "20.04" ]
then
# Run the apply script specified under the Ubuntu 20.04 directory:
source ./UbuntuLatestModuleSubdirectory/apply
elif [ "$(lsb_release -a | grep Release: | awk '{print $2}')" == "18.04" ]
then
# Run the apply script specified under the Ubuntu 18.04 directory:
source ./UbuntuOldModuleSubdirectory/apply
else
# If no match found, run this default script:
source ./defaultApply
# Note: you could also use a variable instead of grabbing the release version, or you could grep for the description to get the OS instead of just the release number, etc.
fi
Here are some good examples of this being done "in the wild".
In this example, different templates are added to the module directory, each designated for a different type of host. The apply statement then reads a variable which is set to the host type, and consequently applies the correct template to the host: https://github.com/P5vc/ServerConfigurations/tree/master/modules/hosts
In this example, the commands are different, however they are relatively compact, so instead of creating subdirectories or entirely separate files, everything is written right into the main apply file: https://github.com/P5vc/ServerConfigurations/blob/master/modules/ufw/apply
I don't have any examples that use entirely separate subdirectories, as most of the modules used by Priveasy handle simple command execution and configuration file placement (plus we always tend to use the latest versions of the same OS's). However, the other reason we don't need too many different files is because we often like to specify the differences within our templates, so that we can execute a single write command, and use mo
to automatically custom-craft the template per system. If you haven't already, I would also look into using mo
, as it can also save you lots of time and space.
Does that make sense? If you still have questions, don't hesitate to ask!
That's fantastic, thanks for that!
Note: That's such good info it might even be worth putting some of it into the README
That's fantastic, thanks for that!
No problem!
it might even be worth putting some of it into the README
Done! :+1:
Quick question on how you recommend organizing modules to be able to handle multiple OSes, or multiple versions of each OS.
For example, a module which installs/configures ntp will have differences in how it does that depending on whether the OS is RedHat or Ubuntu (yum vs apt being the most obvious difference, paths to config files may also differ, etc).
One thought I've had is to create specific modules for each OS and version, so I would have the following modules (assuming that there were significant enough differences between OS versions to warrant separating them):
This would mean that maintaining my modules and mapping of hosts to roles/modules would get a bit finicky though.
Another way I've thought of would be to set a host variable for each server which would contain the OS and version. Then I could have
if
s in the apply of each module.Would love to hear your thoughts though, are there alternative/better ways to achieve this?