Software Engineer

Deploying Tasseo not to Heroku

· by jsnby · Read in about 3 min · (487 Words)
Computers Metrics Graphite Puppet

I’m new to Graphite. From all the buzz on twitter and what I’ve gotten my hands on so far, it’s pretty cool. One of the problems (or features) is that Graphite has a great api, so quite a few third-party dashboards have popped up. Tasseo is one such dashboard. I like it for it’s minimalistic appearance that packs in just enough data to give you everything you need to know in a quick glance. It also helps that it’s pretty easy to deploy.

Jason Dixon(@obfuscurity) designed Tasseo to be deployed easily to Heroku. Unfortunately, I’m not at a company that utilizes their services and we have our own virtual infrastructure. I’m going to cover deploying Tasseo to a minimal CentOS 6 box.

I deploy 100% of the code running on my infrastructure from some form of package management solution. Untarring .tar.gz’s on production hosts doesn’t fly. This means that I’ll need to package Tasseo’s code. I created a spec file to package up Tasseo. Build the RPM and stick it in a yum repository and configure your machine to point at that yum repository.

Now, onto deploying our code. The goal is to have Tasseo running via Passenger under Apache running SSL. Configure your box with access to the Phusion Passenger yum repository and the EPEL repository.

Install some code:

yum install httpd rubygems rubygem-rack mod_passenger rubygem-passenger mod_ssl tasseo ruby-devel gcc-c++
rm -rf /etc/httpd/conf.d/ssl.conf
gem install bundler
cd /usr/share/tasseo
bundle install

Create /etc/httpd/conf.d/tasseo.conf with the following contents:

LoadModule ssl_module modules/mod_ssl.so
Listen 443
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl    .crl
SSLPassPhraseDialog  builtin
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout  300
SSLMutex default
SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin

<VirtualHost *:443>
    ServerName tasseo.example.com
    CustomLog "logs/tasseo_access_log" combined
    ErrorLog  "logs/tasseo_error_log"

    SSLEngine on
    SSLCertificateFile     /etc/pki/tls/certs/localhost.crt
    SSLCertificateKeyFile  /etc/pki/tls/private/localhost.key

    SSLProtocol all -SSLv2
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
    #   Notice: Most problems of broken clients are also related to the HTTP
    #   keep-alive facility, so you usually additionally want to disable
    #   keep-alive for those clients, too. Use variable "nokeepalive" for this.
    #   Similarly, one has to force some clients to use HTTP/1.0 to workaround
    #   their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
    #   "force-response-1.0" for this.
    SetEnvIf User-Agent ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

    DocumentRoot  /usr/share/tasseo/public
    SetEnv GRAPHITE_URL http://graphite
    <Directory    /usr/share/tasseo/public>
        Order      deny,allow
        Deny       from all
        Allow      from *.example.com
    </Directory>
</VirtualHost>

Adjust the GRAPHITE_URL environment variable to point at your graphite install. Please see Tasseo’s README for info on how to configure graphite to allow Tasseo to talk to it. You might have to adjust the allow directive and ServerName directive, add your own authentication settings, and optionally change what ssl certs you are using.

Restart apache. Open up port 443 in your firewall.

Browse to https://yourhost/ and you should get the Tasseo page stating that there are no dashboards found:

Drop a dashboard config file into /usr/share/tasseo/public/d/ and you should be good to go. My puppet manifest to do all of this looks like:

class tasseo (
  $graphite_url='http://graphite'
) {
  include httpd
  include httpd::ssl
  include httpd::passenger

  package { 'tasseo':
    ensure => latest,
    notify => Exec['tasseo bundler install'],
  }

  # Necessary for bundler install
  package { ['ruby-devel', 'gcc-c++']:
    ensure => present,
  }

  package { 'bundler':
    ensure   => latest,
    provider => 'gem',
  }

  exec { 'tasseo bundler install':
    cwd         => '/usr/share/tasseo',
    user        => 'root',
    command     => 'bundle install',
    refreshonly => true,
    logoutput   => on_failure,
    notify      => Service['httpd'],
    require     => Package['bundler', 'tasseo', 'ruby-devel', 'gcc-c++'],
  }

  httpd::conf { 'tasseo.conf':
    content => template('tasseo/httpd.conf.erb'),
    require => Package['rubygem-passenger'],
  }

  firewall { '100 allow https':
    state  => 'NEW',
    dport  => '443',
    proto  => 'tcp',
    action => 'accept',
  }
}

Please note that all the httpd, httpd::ssl and httpd::passenger modules are doing is installing the respective packages….nothing fancy. The httpd::conf define simply creates tasseo.conf in /etc/httpd/conf.d/. Note that I’m also using the puppetlabs-firewall module to manage my iptables configuration.