Puppet modules and the self-contained design - puppet

From Puppet Best Practices:
The Puppet Labs documentation describes modules as self-contained bundles of code and data.
Ok it's clear.
A single module can easily manage a single application.
So, puppetlabs-apache manages Apache only, puppetlabs-mysql manages MySQL only.
.... So, my module my_company-mediawiki manages Mediawiki only (i suppose... with database and virtual host... because a module is self-contained bundles of code and data).
Modules are most effective when the serve a single purpose, limit dependencies, and concern themselves only with managing system state relating to their named purpose.
But my_company-mediawiki needs to depend by:
puppetlabs-mysql: to create database;
puppetlabs-apache: to manage a virtual host.
And... from a rapid search I understand that many modules refer to other modules.
But...
They provide complete functionality without creating dependencies on any other modules, and can be combined as needed to build different application stacks.
Ok, a good module is self-contained and has no dependencies.
So I have to necessarily use the pattern roles and profiles to accomplish these best practices? Or I'm confused...

The Puppet documentation's description of modules as self-contained is more aspirational than definitive. Don't read too much into it, or into others' echoes of it. Modules are quite simply Puppet's next level of code organization above classes and defined types, incorporating also plug-ins and owned data.
Plenty of low-level modules indeed have no cross-module dependencies, but such dependencies inescapably arise when you start forming aggregations at a level between that and whole node configurations. There is nothing inherently wrong with that. The Roles & Profiles pattern is a good way to structure such aggregations, but it is not the only way, and in any case it does not avoid cross-module dependencies because role and profile classes, like any other, should themselves belong to modules.

Related

How to create shared language resources with i18next in multi-app node/express & react monorepo?

I just started to use i18next in my monorepo (new to it), which has several serverside microservices and a couple of frontends, including several custom library components. Many of the language strings are shared, and some are app specific. I could not decide on a logical way to approach the problem.
Tooling: Typescript - Node/Express - React/Vite - Electron/React (Desktop)
Firstly, questions:
Where should I keep the language resources during development? In another library? App in monorepo? Under each library module?
From where should I serve them? Something like lang.mydomain.com? Re-dividing them under each app during build (e.g. with Vite)?
All examples/tutorials I could reach use a single app and use i18next.js/ts to be included at the app level. I think I need to wrap it into a library module for my purposes. How can I do that, without losing access to its capabilities/types/methods etc? Dynamically creating instances in a higher-order module (the library is extensive, and I'm nearly lost)?
My initial thoughts:
As many translations will be shared, translating each one will be illogical, they should be shared.
As there can be many languages, it seems using i18next-http-backend is logical for web and embed with i18next-fs-backend for desktop app.
Dividing the resources as common/graphs/tables/ui etc will be logical (these will be divided in a library module hierarchy though).
A logical way can be to include a module's language resources in the module but that would not help translators, they should be at the same place at the top level in this respect.
PS: I used to use react-intl-universal, it is really easy, but it's release schedule is falling back.
Thank you in advance...

Advantages of using #Module NestJS

I'm making a new NestJS app and after a lot of errors on the first because the multiple modules I created didn't have the correct imports, providers, exports, TypeOrmModule.forFeature etc made me wonder: What was the point?
Why not use only the app.module and just dump everything in it? All the controllers and services and entity types and any other that may come up?
From the documentation:
We want to emphasize that modules are strongly recommended as an
effective way to organize your components
Is that the only reason? Organization?
Does dependency injection play a role of some kind?
Edit:
If organization is the main reason, why not separate in a different folder with a controller and service? Basically a module without the imports, providers etc. Doing the same thing with less boilerplate.
Why not use only the app.module and just dump everything in it?
Better yet, why use multiple files at all? Why not just have a couple thousand line index.js with no types, no organization, just raw JS all the way down?
The answer? Code organization and ease of re-use. By making these modules, you should be grouping together similar logic together. All the code for a single feature should be available by just importing FeatureModule and usable. When it comes to library modules, this becomes pretty apparent: TypeOrmModule has a forRoot/forRootAsync and a forFeature which exposes ways to inject repositories into your services. The JwtModule has a register/registerAsync and exposes a JwtService so you can configure the JwtService once and re-use the provider.
When dealing with entity features this may look messier, but technically it's all still possible, so that in theory you'd be able to take FeatureModule from Application A and drop it into Application B and have everything still working with regards to the FeatureModule, similar to how pulumi has the idea of stacks and applications and you can just spin up new applications using the same group of components.
The module system, once you get the hang of it, and in my opinion, makes it very easy to recognize what all a module will be working with, with regards to other features and how they're connected. It's just a matter of discipline and learning the feature of the framework.

Using terraform modules with in modules

We are working on creating various terraform modules for Azure cloud in our organization. I have a basic doubt on using these modules.
Lets say we have a module created for creating resource groups. When we write a module for storage container, Would it be better to use the resource group module inside the storage module itself or would it be better to let the user terraform script handle it specifying multiple module resource. Eg,
module resourcegroup {
…
}
module storage {
}
Thanks,
Hound
What you're considering here is a design tradeoff rather than a question with a universal answer. With that said, the Terraform documentation section Module Composition recommends that you use only one level of module nesting where possible, and then have the root module connect the outputs from one module into the inputs of another.
One situation where you might decide to go against that advice and create multiple levels of nesting is when you want to write a module which intentionally constrains or raises the level of abstraction of another module written by someone else. Modules shared on Terraform Registry are often very general in order to serve various different use-cases, but those modules might also encapsulate some design best-practices for the system in question and so you might choose to wrap one or more of those general modules in a more specific module that more directly meets your use-case, and hopefully in turn make your "wrapper module" easier to use.
However, it's always important to keep in mind that although Terraform modules can in some sense encapsulate complexity, in the case of Terraform they can't truly hide that complexity the way we might expect for libraries in general-purpose languages, because the maintainer of the root module is ultimately responsible for understanding the full consequences of applying a plan, which involves reviewing all of the proposed changes even to resources encapsulated in nested modules.

Common vs Core - difference

Assume we have a couple of libs. What is the difference between Core and Common library? How should they be recognized and do we organize the responsibilites of both?
+Common
-Class1
+Core
-Class2
+Lib1 has : Common
+Lib2 has : Core, Common
Should Common be truely common (i.e. all libs use it)? Or is Common only for those who need it?
What is good practice when refactoring / creating a project?
I don't really understand the difference between Core and Common.
I think this depends a lot on your particular application. In a single centralized app, I do think there might be a little overlap between the Core and Common folders. But the most important thing is that it makes sense for your app. Don't feel that you need to have those folders just because you've seen it in other apps...
For me, having a Core and a Common folders makes a lot of sense in some scenarios - e.g. a web app with an API and a client. You may have your Core folder in the API side, where the core execution (the business logic) takes place, and then have a Common folder with some things you need in both the API and the client sides - e.g., Http requests validation or a Json converter.
Anyway, it may make sense to have a Core and a Common folder in other kinds of apps.
For example, the Core folder would contain those classes that are central for your app - the vast majority of business model classes would be there.
In the Common folder, on the other hand, you can have some other classes that are shared, but not central - e.g., a Logger or a MessageSender could be there...
As for your little draft of code structure, I think that your Core package is the one to be revised - why Lib1 doesn't use Core? If something is core, generally it's because everything else needs it in order to run. If you do not have code that is conceptually central, maybe you can remove your Core package and keep only Common?
As for your other question - I do not think the Common stuff must be shared by all other packages, but just with 2 or more packages sharing something, that can be considered common.

How far should I go with puppet?

I'd like to preface by saying I'm new to puppet. I have been working with it via vagrant and am starting to feel comfortable writing manifests, but I lack perhaps the experience, or intuition, that can answer my question.
I am trying to grasp how puppet is scoped, and where lines are drawn. I am specifically interested in how this applies to modules and their creation and use.
A more concrete example: the puppletlabs-nginx module. So hypothetically I'm going along my merry way, creating a manifest for a given server role; say it's a dead-simple static file webserver, and I'd like to use nginx. The module will clearly help me with that; there's try_files support and such. I can even ramp up to reverse-proxying via this module. But what if things get stickier? What if there's something I want to do programmatically that I cannot do with the module?
Well, perhaps the short answer is to fix it myself, do a pull request, and go along my merry way. But where does that stop? Is the goal of a community puppet module to support every facet of a given software package? That seems unmanageable. On the other hand, doesn't that create a bunch of mostly-baked modules, build solely from use cases?
Then, there's an analog to Android UI: there are setter methods for what I think is most XML UI definitions. In puppet if feels similar. You can build a config file programmatically, or create it by filling in an ERB template. In other words, I feel the line in puppet between programmatic creation of configuration files and the templated creation of configuration files is blurred; I found no best way with Android and so I don't know which is the way to go with puppet.
So, to the question: what constitutes the ideal puppet module? Should it rely more on templates? On the manifest? Should it account for all configuration scenarios?
From a further-withdrawn perspective it almost seems I want something more opinionated. Puppet's power seems to be flexibility and abstraction, but the modules that are out there feel inconsistent and not as fleshed out.
Thanks for reading...
Thanks to Mark. In just a small amount of time I've switched over to playing with Chef and the modules seem better in regards to many of the concerns I voiced.
In short i can explain you about puppet.
Puppet is nothing but it is an IT automation tool where we can install software's on other machines by creating manifests (recipes or scripts) on master for those softwares to be installed on target machine.
Here master indicates implementation of puppet manifests for softwares.
Target machine indicates agent where softwares to be installed.
Puppet module constitutes of following structure where we do this in master.
In master the path is /etc/puppet/modules to enter into modules directory,you have mentioned puppletlabs-nginx module.so now we can take this module as an example.
After modules directory we have to create files and manifests directories.furthermore,in manifests directory we will create .pp files.For instance, install.pp,uninstall.pp.this is how module structure will be.we usually run these scripts by using few resources like package,service,file,exec etc.
Templates play a minor role in puppet manifests just to hardcore the values.it is not a major part of puppet.Manifests has a great importance in puppet.
For automating any software by using puppet we can follow the above structure.
Thank you.
The PuppetLabs solution here is to use different types of modules for each function -- Components, Profiles, and Roles. See the presentation Designing Puppet: Roles/Profiles Pattern for more information.
The modules available from PuppetForge are of the "Component" type. Their purpose is to be as flexible as possible, while focusing on a single logical piece of software -- e.g., either the apache httpd server OR apache tomcat, but not both.
The kinds of modules that you might write to wrap around one of those Component modules would be a perfect example of a "Profile" module. This could tie apache httpd together along with tomcat and jboss and maybe also some other components like mysql and php. But it's one logical stack, with multiple components. Or maybe you have a LAMP Profile module, and a separate tomcat+jboss Profile module.
The next level up is "Role" modules. They shouldn't have anything in them other than "include" statements that point at the appropriate Profile modules.
See the PuppetLabs presentation for more details, but this logic is pretty similar to what is seen in the Chef world with "wrapper cookbooks".

Resources