User:Giuseppe Lavagetto/Profiles Including Profiles

From Wikitech
Jump to navigation Jump to search

There has been some confusion regarding one of the rules in the Puppet coding style guide, specifically the one about profiles requiring each other. Part of it is I think due to bad wording - which I am responsible for.

The point of underlining that profiles should mostly not include other profiles is that we don't want to create fat profiles that devoid roles of their "composition of functionality" function.

Let's make a simple example: we want to install a python application (ORES) that needs to use a redis database. One might be tempted to do

class profile::ores {
   # ores needs redis on localhost
   require profile::redis
   class {'ores': }
   ...
}

class role::ores {
  include profile::ores
}

This is what we want to prevent. The application can work just fine with a remote redis, so the profile doesn't really require the redis one. The code above should instead be something like

class profile::ores($redis_dsn = lookup(...)) {
   class {'ores': redis_dsn => $redis_dsn}
   ...
}

# Role that installs ores and a local redis cache
class role::ores {
  include profile::redis
  include profile::ores
}

The advantage is clear: you will be able to also define a different role where redis is reached on a remote machine, without having to rewrite all of your classes. Also, your role clearly states what's installed on your server.

Now, let's say our python application needs an UWSGI server to be installed, and we already have a working `profile::uwsgi`. ORES would not work unless this profile is included too.

In this case, you are not only allowed, but encouraged to mark that dependency clearly:

class profile::ores($redis_dsn = lookup(...)) {
   require profile::uwsgi
   class {'ores': redis_dsn => $redis_dsn}
   ...
}

# Role that installs ores and a local redis cache
class role::ores {
  include profile::redis
  include profile::ores
}

Please note that, if you want it to be easy to see that profile::uwsgi is included in the role, you can still add it explicitly to `role::ores`. But `profile::ores` will still need to add the `require` keyword.