Roles and profiles

In 2012, Craig Dunn wrote a blog post (http://www.craigdunn.org/2012/05/239/), which quickly became a point of reference on how to organize Puppet code. He discussed roles and profiles. The role describes what the server represents: a live web server, a development web server, a mail server, and so on. Each node can have one, and only one, role. Note that in his post he manages environments inside roles (two web servers on two different environments have two different roles), as follows:

node www1 { 
  include ::role::www::dev
}
node www2 { 
  include ::role::www::live
}
node smtp1 { 
  include ::role::mailserver
}

Then he introduces the concept of profiles, which include and manage modules to define a logical technical stack. A role can include one or more profiles:

class role { 
  include profile::base
}
class role::www inherits role {
  include ::profile::tomcat
}

In environment related sub roles, we can manage the exceptions we need (here, for example, the www::dev role includes both the database and the webserver::dev profile):

class role::www::dev inherits role::www { 
  include ::profile::webserver::dev
  include ::profile::database
}
class role::www::live inherits role::www { 
  include ::profile::webserver::live
}

Inheritance is usually discouraged in Puppet, particularly on parameterized classes, and it was even removed from nodes. Usage of class inheritance here is not mandatory, but it results in minimized code duplication and doesn't have the problems of parameterized classes, as these classes are only used to group other classes. Alternatives to inheritance could be to include a base profile instead of having a base class, or to consider all roles independent between them and duplicate their contents. The best option would depend on the kind of roles have in our deployment.

This model expects modules to be the only components where resources are actually defined and managed; they are supposed to be reusable (we use them without modifying them) and manage only the components they are written for.

In profiles, we can manage resource and class ordering, we can initialize variables and use them as values for arguments in the declared classes, and we can generally benefit from having an extra layer of abstraction:

class profile::base { 
  include ::networking
  include ::users 
}
class profile::tomcat { 
  class { '::jdk': } 
  class { '::tomcat': } 
}
class profile::webserver {
  class { '::httpd': } 
  class { '::php': } 
  class { '::memcache': } 
}

In profiles subclasses we can manage exceptions or particular cases:

class profile::webserver::dev inherits profile::webserver { 
  Class['::php'] { 
    loglevel   => "debug"
  }
}

This model is quite flexible and has gained a lot of attention and endorsement from Puppet Labs. It's not the only approach that we can follow to organize, in the same way, the resources we need for our nodes, but it's a current best practice and a good point of reference, since it formalizes the concept of role and exposes how we can organize and add layers of abstraction between our nodes and the used modules well.

Note

Note that given the above naming, we would have custom (site) role and profile modules, where we place all our logic. Placing these classes inside a single site module (for example: site::role::www) is absolutely the same and basically just a matter of personal taste and naming and directories layout.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset