Nicolas,

I split this thread since we aren't talking about Kinial anymore.

I think you misunderstood me; I certainly wouldn't advocate the
mishmash of classes you suggest below, as you said, putting the
definition "calls" (I use "declarations", and will in the rest of this
email) in the node statements is easier and more maintainable. Your
problem is a good one, and similar to one I have encountered in my use
of Puppet. The issue at hand seems to be "I'd like to use external
nodes, but I can't because I'd lose the ability to declare defined
resources at the node level." This is the issue I'm addressing, so if
I'm wrong about the problem, let me know.

There are a couple of approaches to the problem you describe. The
first step is almost always to take a step back and ask yourself if
you have designed your solution in a way that makes the best use of
the tools you've chosen. Puppet shines at creating repeatable
configurations across a number of machines; creating mostly similar,
but somewhat different configurations on each individual machine,
while a related problem, is not the same thing. So, one thing I might
ask myself in the situation you describe is this: does each machine
really need to have a different set of webapp-instances? Are there
resource constraints, or are you just following a (reasonable!) habit
of only putting what is necessary on any given server? If you find
that there really isn't any reason, you can address this problem by
creating a class that defines all the webapp-instances and including
that class on every node.

To make the solution more interesting, though, let's assume that there
is a solid reason not to deploy all the countries to every application
server. The next question we ask is: how can we put these definitions
within a class without losing the flexibility/maintainability we get
from node-level declarations? Depending on the internal implementation
of your definition, Puppet arrays might come to your rescue:

node node1 {
  countries = ["es", "fr", "uk"]
  include webapp
}

node node2 {
  countries = ["es", "it", "de"]
  include webapp
}

class webapp {
  webapp-instance {
    "app":
      countries => $countries;
  }
}

We had a similar issue that I dealt with in a slightly different way.
We have this concept of database instances that have a name (a
numerical id of the "slot" of the instance), a port they run on, and a
replication statement. So we have something like:

define db::instance($port, $replicate_db)

The instances required vary by machine, a specific instance isn't
always on a given port, etc. So I had trouble mapping this to classes
(especially for machines that needed multiple instances of the same
"type" running on different ports). For a long time we did this at the
node level:

node qa-db {
  db::instance {
    "0":
      port => 3306,
      replicate_db => production;
    "1":
      port => 3307,
      replicate_db => production;
  }
}

Then we decided to switch to external nodes... and there was a bit of
trouble. It was easy enough to write classes for each instance type
and set a variable for the slot, but I ht a wall on machines that
needed multiple instances that were identical except for slot#/port.
Then I remembered arrays:

class zomg_read {
  db::instance {
    $zomg_read_slot:
      port => $zomg_read_slot + 3306,
      replicate_db => production;
  }
}

node qa-db {
  $zomg_read_slot = [0, 1]
  include zomg_read
}

Since using arrays creates multiple resources, this works really well,
and pulls the definitions into a class without losing the flexibility
required to migrate to external nodes.

Obviously, not knowing everything about your situation, I can't solve
your problem completely but I can say that, in my experience, when the
tool seems like it is getting in my way I am often not using the tool
the way it was designed to be used. Puppet is a somewhat opinionated
tool, in some ways, in that there are design decisions made to support
the Puppet model of the world, and you may have to adjust your design
to fit that model (or pick a different tool, I suppose). Not that we
can't change the tool where merited, but in this case, I think Puppet
has it right.

--Paul

On Tue, Feb 10, 2009 at 12:16 AM, nicolas <ncapp...@yahoo.fr> wrote:
> ok paul, thanks for clarifying this.
>
> I think my misconception comes from what we're trying to do.
>
> We have webapps that have instances defined for different set of
> countries
> So we have definitions like :
>   define webapp-instance($countries, ...)
>
> And then for a set of machines we want to deploy our instances, but no
> machine has the exact same requirement :
> node node1 {
>    webapp-instance { "es_fr", countries = ["es", "fr"] }
>    webapp-instance { "uk", countries = ["uk"] }
> }
> node node2 {
>    webapp-instance { "es_it", countries = ["es", "it"] }
>    webapp-instance { "de", countries = ["de"] }
> }
> and so on...
>
> So, if I follow your guidelines, I should define intermediate classes
> and then use theses classes in the nodes
> class webapp_instance_es_fr {
>   webapp-instance { "es_fr", countries = ["es", "fr"] }
> }
>
> class webapp_instance_uk {
>   webapp-instance { "uk", countries = ["uk"] }
> }
>
> class webapp_instance_"de" {
>   webapp-instance { "de", countries = ["de"] }
> }
>
> and then put theses classes in my nodes :
> node node1 {
>   include webapp_instance_es_fr
>   include webapp_instance_uk
> }
>
> Although this step makes sense, it happens that using "definition
> call" (how should I say ?) directly in nodes is easier because people
> in charge of managing nodes don't have to write intermediate classes
> that only act as wrapper.
> As there is almost no machine with the same country configuration
> (that is, a class will only be used by one machine in practice), the
> overhead of writing intermediate classes gives no real benefits, even
> if conceptually cleaner.
>
> Any comment on this ?
>
> thanks
>
> nicolas
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To post to this group, send email to puppet-users@googlegroups.com
To unsubscribe from this group, send email to 
puppet-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/puppet-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to