Background
This is a record of the discussion on the 12th regarding the new layout of all SIMP Puppet Component Modules
As we were working through issues regarding - SIMP-57Getting issue details... STATUS , we started discussing how to bring additional consistency to our module footprint and make it easier to adopt across the board.
Our decision ended up being as follows.
Basic Module Structure
Our component modules will be patterned after the Puppet Labs suggested layout du jour. SIMP additions are in bold below.
- module/manifests/
- init.pp
- params.pp
- install.pp
- config.pp
- service.pp
- firewall.pp
- logging.pp
- audit.pp
- selinux.pp (this one may just have to be mixed in at times, however, any boolean flipping should probably be done here)
Each of these items in bold must adhere to the following
- They must be disabled by default
- They must be name-based where the Boolean true and the Stringsimp amount to the same action.
- They must allow for an ENC since we want maximum module uptake where possible
This will look something like the following
$enable_firewall = defined($::enable_firewall) ? $::enable_firewall : hiera('enable_firewall',false)
- Yes, this does mean that these features are disabled by default in the modules. However, they will be enabled by default in simp-core, so we're ensuring maximum safety for downstream users.
- Can we make this a function? Is that too much trouble/obfuscation?
Advanced Module Structure
Some modules may manage components that do not easily fit the recommended structure.
- If the module has taken on too much responsibility for a single component, refactor it into separate component modules and use the recommended structure.
- If the module manages a single responsibility yet is inherently complex, apply the recommended structure to appropriate areas.
Below are two recommended patterns for complex adaptations:
Modules that manage a client and a server
This pattern applies to any module that manages multiple related-but-asymmetric services, such as a client and server.
The general pattern is to:
- create a namespace (directory) for each service
- apply the basic structure to each namespace
- continue to use the basic (top-level) module structure to manage module-wide configurations and resource orderings
Separate Client and Server Components
In the case that you have a server and client that are two separately isolated services, such as the SSH server and client, then two separate modules should be created. This provides for a clean usage pattern over time.
Combined Client and Server Components
There are going to be times where the server and client components cannot be split. In these cases, isolate the functionality within the module to the bests of your ability and repeat the pattern below each subdirectory segment.
As an example, you may use something like the following:
- module/manifests/
- init.pp
- params.pp, config.pp, etc (for module-wide settings)
- server.pp
- server/
- params.pp
- install.pp
- config.pp
- service.pp
- firewall.pp
- logging.pp
- audit.pp
- selinux.pp
- client.pp
- client/
- params.pp
- install.pp
- config.pp
- service.pp
- firewall.pp
- logging.pp
- audit.pp
- selinux.pp
NOTE: Many legacy modules will use an earlier client/server pattern in init.pp
where the Boolean parameters $is_client
and $is_server
. To maintain compatibility, keep the parameters in init.pp
and .
Modules that manage their own internal "services"
Occasionally there may be a component (like xinted) that manages multiple services of its own. Managing these services
- module/manifests/
- init.pp
- params.pp
- config.pp
- config/inet_service.pp (a define that configures an inet_service)
- service.pp
- firewall.pp
- firewall/inet_service.pp (a define that establishes firewall rules for the inet_service)
- logging.pp
- audit.pp
- selinux.pp (this one may just have to be mixed in at times, however, any boolean flipping should probably be done here)