Boyan Tabakov
2013-Apr-15 10:02 UTC
[Puppet Users] Module structure for case-specific configuration
Hi all, Let''s consider the following situation: I use the module structure, proposed by R.I.Pienaar: http://www.devco.net/archives/2012/12/13/simple-puppet-module-structure-redux.php I have a module, let''s say apache, that follows that pattern for installing and setting up basic apache server. However, I also want to have a way to provide extra configuration for specific use-cases. Let''s call these projects. So for each project, we want to have some additional class apache::projectX that performs these additional tasks (e.g. deploys more specific template, defines more file resources, etc, etc). My question is this: if I want to stick with a single point of entry to the module (i.e. manifests include just apache module with some parameter), what''s the best way to go considering that each project subclass may have its own set of parameters? Defining all these parameters on the apache class itself, doesn''t sound like a good idea. Perhaps, defining them in Hiera as apache::projetX::parameterY? The easy solution seems to be to forget about single point of entry and include from manifests both the apache and the apache::projectX classes with appropriate parameters. However, in order to ensure proper sequencing all the apache::projectX classes might need to contain some code like this: Class[''apache::config''] -> Class[''apache::projectX''] ~> Class[''apache::service''] I don''t like the idea of having this in all project-specific classes, as modification of the module structure might become more difficult - i.e. will need to change all the apache:projectX classes if I want to add, let''s say, a apache::modules class that needs to load before the projectX. Any thoughts on a best practice in similar situations? Regards, Boyan
jcbollinger
2013-Apr-15 15:02 UTC
[Puppet Users] Re: Module structure for case-specific configuration
On Monday, April 15, 2013 5:02:06 AM UTC-5, Boyan Tabakov wrote:> > Hi all, > > Let''s consider the following situation: > > I use the module structure, proposed by R.I.Pienaar: > > http://www.devco.net/archives/2012/12/13/simple-puppet-module-structure-redux.php > > I have a module, let''s say apache, that follows that pattern for > installing and setting up basic apache server. > > However, I also want to have a way to provide extra configuration for > specific use-cases. Let''s call these projects. So for each project, we > want to have some additional class apache::projectX that performs these > additional tasks (e.g. deploys more specific template, defines more file > resources, etc, etc). > > My question is this: if I want to stick with a single point of entry to > the module (i.e. manifests include just apache module with some > parameter), what''s the best way to go considering that each project > subclass may have its own set of parameters? Defining all these > parameters on the apache class itself, doesn''t sound like a good idea. > Perhaps, defining them in Hiera as apache::projetX::parameterY? > > The easy solution seems to be to forget about single point of entry and > include from manifests both the apache and the apache::projectX classes > with appropriate parameters. However, in order to ensure proper > sequencing all the apache::projectX classes might need to contain some > code like this: > > Class[''apache::config''] -> > Class[''apache::projectX''] ~> > Class[''apache::service''] > > I don''t like the idea of having this in all project-specific classes, as > modification of the module structure might become more difficult - i.e. > will need to change all the apache:projectX classes if I want to add, > let''s say, a apache::modules class that needs to load before the projectX. > > Any thoughts on a best practice in similar situations? > >Single point of entry does not serve well and is not a particularly useful goal when the desired results are very divergent. The single declaration then becomes magical, and therefore difficult to understand and maintain. I think your specific case is even more distinguished than that, however: it sounds like you are inappropriately modeling web *site* components (i.e. content) as part of the web *server*. I would pull the projects out as completely separate modules (and that could restore your single point of entry, on a per-module basis). Yes, your project modules might need to declare some relationships, but that is in no way a function of which module contains each class. Note also that you should *not* be using subclasses for any of what you described. It''s not clear whether you actually are doing so, despite your use of the term, but Puppet class inheritance is a very special- (and limited-)purpose tool that does not apply to any of the needs you described. It looks like you may simply be putting some classes in others'' namespaces, however, and that''s an *entirely* different thing. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Boyan Tabakov
2013-Apr-16 08:52 UTC
Re: [Puppet Users] Re: Module structure for case-specific configuration
Hi John, Thanks for your reply! On 15.4.2013 18:02, jcbollinger wrote:> Single point of entry does not serve well and is not a particularly > useful goal when the desired results are very divergent. The single > declaration then becomes magical, and therefore difficult to understand > and maintain.That makes sense.> I think your specific case is even more distinguished than that, > however: it sounds like you are inappropriately modeling web /site/ > components (i.e. content) as part of the web /server/. I would pull the > projects out as completely separate modules (and that could restore your > single point of entry, on a per-module basis). Yes, your project > modules might need to declare some relationships, but that is in no way > a function of which module contains each class.It is not website related components, but indeed web-server - vhost definitions, special apache configuration files (e.g. module configuration overrides, etc). Besides, the apache was just an example, I have other cases where similar setup is required. In any case, the project-specific definitions are *only* for resources, directly related to the module in question (in this case, apache).> Note also that you should /not/ be using subclasses for any of what you > described. It''s not clear whether you actually are doing so, despite > your use of the term, but Puppet class inheritance is a very special- > (and limited-)purpose tool that does not apply to any of the needs you > described. It looks like you may simply be putting some classes in > others'' namespaces, however, and that''s an /entirely/ different thing. >Pardon my wording. By subclasses, I just meant a class inside some module (apache::projectX). No inheritance involved. If single point of entry can be avoided, then what do you think about the second part of my question? :> The easy solution seems to be to forget about single point of entry and > include from manifests both the apache and the apache::projectX classes > with appropriate parameters. However, in order to ensure proper > sequencing all the apache::projectX classes might need to contain some > code like this: > > Class[''apache::config''] -> > Class[''apache::projectX''] ~> > Class[''apache::service''] > > I don''t like the idea of having this in all project-specific classes, as > modification of the module structure might become more difficult - i.e. > will need to change all the apache:projectX classes if I want to add, > let''s say, a apache::modules class that needs to load before the projectX.BR, Boyan
jcbollinger
2013-Apr-16 13:30 UTC
Re: [Puppet Users] Re: Module structure for case-specific configuration
On Tuesday, April 16, 2013 3:52:40 AM UTC-5, Boyan Tabakov wrote:> > > It is not website related components, but indeed web-server - vhost > definitions, special apache configuration files (e.g. module > configuration overrides, etc). Besides, the apache was just an example, > I have other cases where similar setup is required. In any case, the > project-specific definitions are *only* for resources, directly related > to the module in question (in this case, apache). > [...] > If single point of entry can be avoided, then what do you think about > the second part of my question? : > > > The easy solution seems to be to forget about single point of entry and > > include from manifests both the apache and the apache::projectX classes > > with appropriate parameters. However, in order to ensure proper > > sequencing all the apache::projectX classes might need to contain some > > code like this: > > > > Class[''apache::config''] -> > > Class[''apache::projectX''] ~> > > Class[''apache::service''] > >[... which carries maintenance costs typical of such boilerplate repetition.] It sounds to me like requiring an explicit declaration for each project class is the way to go. As I said already, however, that''s entirely unrelated to the question of avoiding repetitive declaration patterns. You might be able to use collections to solve this problem. Proceed carefully, as Puppet has at times had issues with collecting classes (as opposed to ordinary resources), but the basic idea would be for Class[''apache''] to contain something along these lines: Class[''apache::config''] -> Class<| tag == ''apache::project'' |> ~> Class[''apache::service''] That way, you have the needed relationship declarations in one central place. It should not cause project classes that you have not otherwise declared to be declared, and I don''t think it will be sensitive to the order of your declarations. You will probably find that you need to tweak that somewhat to get it to work is you want, however. You might find that it helps to require each (top) project class to explicitly tag itself with some well-known tag. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Boyan Tabakov
2013-Apr-18 06:34 UTC
Re: [Puppet Users] Re: Module structure for case-specific configuration
On 16.4.2013 16:30, jcbollinger wrote:> [... which carries maintenance costs typical of such boilerplate > repetition.] > > It sounds to me like requiring an explicit declaration for each project > class is the way to go. As I said already, however, that''s entirely > unrelated to the question of avoiding repetitive declaration patterns. > > You might be able to use collections to solve this problem. Proceed > carefully, as Puppet has at times had issues with collecting classes (as > opposed to ordinary resources), but the basic idea would be for > Class[''apache''] to contain something along these lines: > > Class[''apache::config''] -> Class<| tag == ''apache::project'' |> ~> > Class[''apache::service''] > > That way, you have the needed relationship declarations in one central > place. It should not cause project classes that you have not otherwise > declared to be declared, and I don''t think it will be sensitive to the > order of your declarations. You will probably find that you need to > tweak that somewhat to get it to work is you want, however. You might > find that it helps to require each (top) project class to explicitly tag > itself with some well-known tag. >Thanks! That sounds good. Will try it out. BR, Boyan