Ask Your Question

Roles-and-profiles best practices for apache vhosts?

asked 2015-08-04 17:57:19 -0600

JohnsonEarls gravatar image

updated 2015-08-04 18:40:22 -0600

I'm running into a lot of problems trying to figure out the "right way" to implement the roles-and-profiles model. All the examples I've found on the web are simplified, idealized examples that don't really discuss how to actually derive separate and independent "profiles" and functional modules for your server functionality.

My specific instance in this case is apache vhosts: In building a configuration for a server that manages yum repos via the "mrepo" software and provides access to them via apache, it's easy to see that you have a profile for a web server and a profile for the yum repo management via mrepo. However, where does the vhost fall in? Is it part of, or derived from, the web server profile, even though it's specific to the yum repo management? Is it part of the yum repo management profile, even though it's technically not part of the mrepo technology that is supposed to be defined by that profile?

I can see three ways to implement this:

1) the vhost is defined in a sub-profile of the web server profile:

class profile::webserver::yum {
    apache::vhost { "yum":

2) the vhost is defined directly as part of the mrepo server profile

class profile::mrepo_server {
    apache::vhost { "yum":

3) the vhost is defined as an independent profile

class profile::yum_web_access {
    apache::vhost { "yum":

None of these seem really palatable to me. The first example (profile::webserver::yum) is the closest to acceptable, but that involves modifying the webserver profile (in a logical sense, anyway, since all the profiles are in the same module anyway) as part of building other technologies, which seems wrong.

Edit: Or maybe I'm completely off-base here? Should my webserver and mrepo_server "profiles" actually be component modules, and I really just have one profile for my yum server? ... Sigh. This is an example of how confused I am about how this model should be applied to a real problem.

Alternately, if anyone has any links to real-world implementations of the roles-and-profiles model, in an environment that was not constructed just to play nice with that model, that would be tremendously helpful in figuring this stuff out.

Thanks in advance, - Johnson

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted

answered 2015-08-05 11:15:59 -0600

ramindk gravatar image

If you start with the role, I believe role/profile maker more sense. You role is a yum server. That's what the server does. Now we add our reusable profiles to create the role.

class role::yum_server {

  include ::profile::apache
  include ::profile::mrpeo

I'm a fan of using create_resources to add things like vhosts, users, anything you may have more than on of.


apache::vhosts: {}


class profile::apache {

  include ::apache
  include ::collectd
  include ::logrotate
  include ::sslcerts

  collectd::plugins { 'apache': }  
  logrotate::simple { 'apache'': }

  $myvhosts = hiera('apache::vhosts', {})
  create_resources('apache::vhost', $myvhosts)

  Sslcerts::Cert<||> -> Class['apache::service']

Keep in mind that this is just one way to do it. Profiles are where youget to be opinionated. They are your least shareable code with other people IMO. This answer might be helpful as well,

edit flag offensive delete link more


Thank you. I'm not going to use create_resources, since i feel that hides some of what's going on in a way that the other folks on my team might not follow, but having a separate web server profile is the way i ended up going.

JohnsonEarls gravatar imageJohnsonEarls ( 2015-08-09 17:00:04 -0600 )edit

answered 2015-08-05 03:48:24 -0600

fvoges gravatar image

In this case, both things go together. The web server is useless without mrepo and mrepo is useless without a web server. You application stack requires both working together.

So the answer is, you configure all the components required to setup your Yum server into a single profile. For example,

class profiles::yum_server {
  include apache
  class { 'mrepo::params':
    src_root       => '/vol/repos',
    www_servername => $::fqdn,

  mrepo::repo { "centos6-x86_64":
    ensure    => present,
    update    => "nightly",
    repotitle => "CentOS 6.6 64 bit",
    arch      => "x86_64",
    release   => "6.6",
    urls      => {
      os          => 'rsync://$release/$repo/$arch/',
      extras      => 'rsync://$release/$repo/$arch/',
      scl         => 'rsync://$release/SCL/$arch/',
      updates     => 'rsync://$release/$repo/$arch/',

  mrepo::repo { "epel6-x86_64":
    ensure    => present,
    update    => "nightly",
    repotitle => "EPEL 6 64 bit",
    arch      => "x86_64",
    release   => "6",
    urls      => {
      epel         => 'rsync://$repo/$release/$arch/',

Ideally, the data should not be hard coded and come from hiera instead.

A more complex example,

class profiles::wordpress {
  $mysql_root_pw = hiera('profiles::wordpress::mysql_root_pw')
  $docroot       = hiera('profiles::wordpress::docroot')
  $wp_user       = hiera('profiles::wordpress::user')
  $wp_pass       = hiera('profiles::wordpress::pass')
  $wp_group      = hiera('profiles::wordpress::group')
  $db_name       = hiera('profiles::wordpress::db_name')
  $db_user       = hiera('profiles::wordpress::db_user')
  $db_pass       = hiera('profiles::wordpress::db_pass')

  include vsftpd

  user { $wp_user:
    ensure     => present,
    password   => $wp_pass,
    gid        => $wp_group,
    managehome => true,

  group { $wp_group:
    ensure => present,

  file { '/etc/ftpusers':
    ensure => file,

  file_line { 'wordpress user access':
    ensure => present,
    path   => '/etc/ftpusers',
    line   => $wp_user,

  include apache
  include apache::mod::php
  class { 'mysql::server':
    root_password => $mysql_root_pw,

  class { 'mysql::bindings':
    php_enable => true,
    notify     => Class['::apache::service'],

  apache::vhost { $::fqdn:
    docroot        => $docroot,
    manage_docroot => false,

  class { '::wordpress':
    install_dir => $docroot,
    wp_owner    => $wp_user,
    wp_group    => $wp_group,
    db_name     => $db_name,
    db_user     => $db_user,
    db_password => $db_password,

And the hiera data for that profile would be,

profiles::wordpress::mysql_root_pw: 'hohmaeluomauZohbeo7TohraeWucaiz8'
profiles::wordpress::docroot: '/opt/www'
profiles::wordpress::user: 'wordpress'
# Password is 'wordpress'
profiles::wordpress::pass: '$1$l8yDV3Ix$ttcq0gAsV57xEtAE2Ef180'
profiles::wordpress::group: 'wordpress'
profiles::wordpress::db_user: 'wordpress'
profiles::wordpress::db_name: 'wordpress'
profiles::wordpress::db_pass: 'bb69laskdj381b4b9de3a232'
edit flag offensive delete link more


Thank you for the detailed answer. After considering both, I went with ramindk's 's model; that seems to better fit how i'm thinking about the profiles (I realized we're going to have many different apps with web server front ends, so it makes sense to me for web server to be a different profile)

JohnsonEarls gravatar imageJohnsonEarls ( 2015-08-09 16:58:55 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2015-08-04 17:57:19 -0600

Seen: 683 times

Last updated: Aug 05 '15