RabbitMQ Lossless Installation via Puppet

This article explains how to install a production ready RabbitMQ instance via Puppet in a way that allows the host OS to be destroyed and recreated without data loss relating to the queue state.

Most VPS providers allow you to define and mount multiple disks on your server. A typical split might look like this:

  • OS
  • Swap
  • Data

Typically an administrator will create these disks once, and when required will destroy the OS disk but leave the Data disk intact. If RabbitMQ is installed directly on the OS without a Data mount, then reinstalling the OS will result in the loss of your data, however if we configure rabbitMQ to use the data disk for storage, then we can resume our application’s state in the event that we have to rebuild the server.

Puppet manifest

We must create the following manifest:

include ufw

class { 'jdk_oracle': }

ufw::allow { "allow-rabbitmq-from-dev":
  from => "127.0.0.1",
  port => 5672,
}

ufw::allow { "allow-rabbitmq-admin-from-dev":
  from => "127.0.0.1",
  port => 15672,
}

mount { 'data':
  device  => '/dev/sdc',
  ensure  => 'mounted',
  name    => '/data',
  atboot  => true,
  dump    => 0,
  fstype  => 'ext4',
  options => 'noatime,errors=remount-ro',
  pass    => 1,
  require => File['datadir'],
}

file { 'datadir':
  path   => '/data',
  ensure => 'directory',
  mode   => 777,
}

file { 'rabbitmqdir':
  path    => '/data/rabbitmq',
  ensure  => 'directory',
  mode    => 777,
  require => Mount['data'],
}

file { '/data/rabbitmq/logs':
  ensure  => 'directory',
  mode    => 777,
  require => File['rabbitmqdir'],
}

file { '/data/rabbitmq/data':
  ensure  => 'directory',
  mode    => 777,
  require => File['rabbitmqdir'],
}

#rabbitmq
class { 'rabbitmq':
  service_manage        => true,
  port                  => '5672',
  delete_guest_user     => true,
  environment_variables => {
    'RABBITMQ_MNESIA_BASE' => '/data/rabbitmq/data',
    'RABBITMQ_LOG_BASE'    => '/data/rabbitmq/logs',
    'RABBITMQ_MNESIA_DIR'  => '/data/rabbitmq/data/localhost'
  }
  ,
  require               => [File['/data/rabbitmq/data'], File['/data/rabbitmq/logs']],
}

rabbitmq_user { 'prodid':
  admin    => true,
  password => 'prodidPassword',
}

rabbitmq_user { 'user':
  admin    => true,
  password => 'rabbitMQPa$$word',
}

rabbitmq_vhost { 'domain': ensure => present, }

rabbitmq_user_permissions { 'user@domain':
  configure_permission => '.*',
  read_permission      => '.*',
  write_permission     => '.*',
}

rabbitmq_user_permissions { 'prodid@domain':
  configure_permission => '.*',
  read_permission      => '.*',
  write_permission     => '.*',
}

The above puppet manifest mounts the data disk, creates a data folder, and a rabbitmq directory inside this.

In the event that the operating system disk is replaced the rabbitMq data folder is safe on another disk. Note how we also configure the firewall, and segregate the responsibilities for the prodid vs the human user.