Archive for notes

Route53 DNS Round-Robin CNAMEs with Weighted Sets

According to RFC1034, CNAMES cannot reference multiple canonical hosts in the RDATA section. In other words, you can’t have the CNAME “www.domain.com” alias (or resolve to) “www1.domain.com” and “www2.domain.com”.

This sucks because you may want to use DNS for round-robin (RR) load-balancing across CNAME records much like you would for A records. The good news is that Route53 supports “Weighted Sets” which allow you to do round-robin-eque load balancing between multiple CNAMEs. For example, you might want to distribute your load evenly between multiple AWS regions like us-west-1 and us-west-2 that each contain an Elastic Load Balancer (ELB).

The other possibility is you cannot use an ELB because a particular service is private. Remember, services behind an ELB are internet accessible from 0.0.0.0/0; ELBs themselves cannot be controlled by security groups.  Using A records, one can do DNS-RR to either the public or private IP address on an instance, but not both (it just wouldn’t make sense). The drawback here is that you cannot use the same hostname for services that are inside Ec2 as services that are outside of Ec2. If instead, you use a Weighted-Set with a short TTL (e.g. 10 seconds), you can create a CNAME that points to the CNAMEs of each of the EC2 instances. Because the CNAME points to another CNAME, when it’s resolved inside of EC2 a private ip address is returned; conversely when it’s resolved from outside of EC2 a public IP address is returned.

The reason it’s important to return either a public or private IP address is due to the way EC2 security groups work. When an ingress rule is granted from a particular security group (e.g. allow “Group A” to access “Group B”), it only applies to the private IP addresses of instances in “Group A”. This means that when instances in “Group A” need to access instances in “Group B”, they should use the private IP address of instances in “Group B”. Using the CNAME of an EC2 instance ensures you’re always connecting to the most appropriate IP address whether your inside or outside of EC2.

 

 

 

 

Building Varnish Debian/Ubuntu Package From Souce

Varnish-cache.org is nice about providing a lot of binary packages for most distros/releases, but not for all architectures. As a result, you may find yourself needing to build the packages by hand. Here’s how I went about it for Varnish-2.1 on an old Ubuntu release.

Add the Varnish apt repo to your /etc/apt/sources.list:

deb http://repo.varnish-cache.org/ubuntu/ hardy varnish-2.1 deb-src http://repo.varnish-cache.org/ubuntu/ hardy varnish-2.1

Add the Varnish distributors GPG key:

curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add -

Update your repo cache:

sudo apt-get update

Download & compile source:

sudo apt-get source varnish cd /usr/src dpkg-source -x varnish_2.1.2-1*.dsc cd varnish-2.1.2 && dpkg-buildpackage

Then, in /usr/src/ you’ll find your new .deb packages ready for installation.

Using MacPorts on OSX Lion

After upgrading to OSX Lion, my MacPorts installation failed. I upgraded to OSX XCode 4.1, and then console compilation stopped working. Apparently, by default the “UNIX Development” tools and “System Development” tools are not installed when installing via the App Store. Fortunately, there’s an easy (time consuming) fix. Simply re-run the “Install XCode” app in your Applications directory. It’s easily located by using Spotlight.

Warning: port definitions are more than two weeks old, consider using selfupdate Warning: Xcode does not appear to be installed; most ports will likely fail to build. Error: Unable to open port: can’t read “build.cmd”: Failed to locate ‘make’ in path: ‘/opt/local/bin:/opt/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin’ or at its MacPorts configuration time location, did you move it? Error: Unable to execute port: upgrade gettext failed

‘xterm-256color’: unknown terminal type.

After upgrading to OSX Lion, I started getting this error on certain (Debian/Ubuntu) servers. The fix is simply to install the “ncurses-term” package which provides the file /usr/share/terminfo/x/xterm-256color.

Porting Fedora RPM Spec File to CentOS Error: find: invalid predicate

I’ve been porting many spec files from fc15 to el5. In the process, a common error that is encountered is:

find: invalid predicate `’ error: Bad exit status from /var/tmp/rpm-tmp.63066 (%install) RPM build errors: Bad exit status from /var/tmp/rpm-tmp.63066 (%install)

The fix is almost always that BuildRoot is not defined in the spec file. Defining one near the top of the file will resolve the issue.

BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot

Symfony: Configuration file does not have a registered handler

I was getting the following error in an older Symfony 1.2 project. Running the standard

symfony cc
didn’t resolve the issue as the symfony command itself relied on files in cache/. Turns out that after some files had been moved around on the filesystem, which made symfony unhappy. A simple
rm -rf cache/*
fixed the problem.

Configuration file “/opt/symfony/1.2/lib/config/config/settings.yml, /opt/symfony/1.2/lib/plugins/sfProtoculousPlugin/config/settings.yml, /vol/svn/cms/plugins/sfJqueryReloadedPlugin/config/settings.yml, /vol/svn/cms/apps/frontend/config/settings.yml” does not have a registered handler.

Recursively Create & Install MacPorts with cpan2port

Recently I posted on how to create native MacPorts of Perl modules, which is useful when the Perl modules you need are not included in the distribution. The problem I quickly ran into is that dependencies were not being followed. Attempting to install Net::Amazon::S3 on my MacBook would probably have taken hours had I not whipped up this script.

Some smart alec is probably going to mention that the CPAN module has done this for ages, why not just use it? My problem with using the CPAN module on top of MacPorts is that that don’t play with each other, which results unsatisfied MacPort dependencies and thus duplicate installs.

#!/usr/bin/env perl # # Recursively create and install MacPorts for Perl modules using cpan2port # # Author: Erik Osterman #

use IO::Handle; use IPC::Open2; use strict;

$|++; my $module = shift; my %cache;

&install($module);

sub install { my $module = shift; print “Building $module\n”; $cache{$module} = 1; my ($read_fh, $write_fh) = (IO::Handle->new(), IO::Handle->new()); open2($read_fh, $write_fh, “./cpan2port -t $module 2>&1″) or die

my $port = undef; while(my $line = ) { chomp($line); # “Shall I follow them and prepend them to the queue of modules we are processing right now?” if($line =~ /Shall I follow/) { print $write_fh “yes\n”; } # creating perl/p5-datetime-format-flexible/Portfilecandidate Module::Pluggable if($line =~ /^creating\s+(.*?)\/Portfilecandidate/) { $port = $1; } # DateTime::TimeZone is not perl porter elsif($line =~ /^([^\s]+)\s+is not perl porter/) { unless(exists $cache{$1}) { print “Found dependency: $1\n”; &install($1); } } } close($read_fh); close($write_fh); if($port) { print “Installing $port\n”; system(“sudo port install $port”); } else { print “No port file found\n”; } }