P5vc / fetch-apply

Transparent Server Configuration and Management
MIT License
17 stars 3 forks source link

Recomendation for managing multiple OSes (and multiple versions of each) #4

Closed emmetog closed 3 years ago

emmetog commented 3 years ago

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 ifs in the apply of each module.

Would love to hear your thoughts though, are there alternative/better ways to achieve this?

P5vc commented 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!

emmetog commented 3 years ago

That's fantastic, thanks for that!

Note: That's such good info it might even be worth putting some of it into the README

P5vc commented 3 years ago

That's fantastic, thanks for that!

No problem!

it might even be worth putting some of it into the README

Done! :+1: