Deploying Tasseo not to Heroku
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.