Why naming your servers properly is important to your startup

April 16, 2011

Server hostnames are important and they should be carefully thought out before a startup builds out its infrastructure. At the very least they should be descriptive enough to allow a technical person to loosely identify the servers business purpose.

Let me describe how I setup puppet manifest with descriptive server hostnames.

Firstly, I’ll point out why its important you need to think about a server hostname standard. Later you’ll see how this pays off when it comes to Puppet, the automated system configuration tool developed by Puppetlabs.

prod.lon.uk

Lets say a server with a hostname webserver.example.com hooks into example.com’s infrastructure.

The problem with using a simple and very much non-descriptive hostname such as webserver.example.com is that the hostname itself provides very little information on the server’s purpose. All we know is that its a webserver belonging to example.com.

  • Is it a development or production webserver?
  • Physically, where is this server located?
  • Is this the only webserver that belongs to example.com?

To resolve these issues, its important to provide descriptive hostnames to servers based on a meaningful namespace. By changing webserver.example.com to web01.prod.lon.uk.example.com we can immediately determine the following characteristics of the server and example.com’s infrastructure .

  • It is 1 of potentially many web servers.
  • It is a production web server.
  • The server is physically located in the United Kingdom.
  • More specifically it is located in London.
  • It can be assumed that this server has a corresponding DEV, UAT, SVP and DR server which shares a similiar name (example; web01.dev.lon.uk.example.com).

These points are important in the way we can now handle nodes within example.com’s infrastructure using puppet.

Puppet supports classes which can be included by nodes. A class contains puppet manifest which is used to describe how the server is to be configured. Nodes in puppet define which servers can connect to puppetmasterd and pull down the manifest.

Below are node definitions for 3 servers. See how easy it is to identify the function of each server when we use a structured hostname standard?

node /web01.prod.lon.uk.example.com/ {
    include node_prod
    include node_lon
}

node /web01.prod.bej.cn.example.com/  {
    include node_prod
    include node_bej
}

node /web01.dev.cn.sha.example.com/ {
    include node_dev
    include node_sha
}

By using ‘include node_prod’ web01.prod.lon.uk.example.com will include a class with a name of ‘node_prod’. Likewise for web01.prod.bej.cn.example.com. web01.dev.cn.sha.example.com will include the ‘node_dev’ class. All 3 nodes will also include the class which is named after the city they are located in.

Moving onto the root, prod and dev classes, I then begin to define system configuration that should be applied to all servers that belong to example.com and then by building an environment class such as ‘node_prod’ I can be more specific about which configuration is applied to what server based on where it sits within example.com’s infrastructure.

Below I’m defining a hosts entry for ‘prod-smtp-server’ for all servers that include the ‘node_prod’ class which sit in the production environment. For development servers which include the ‘node_dev’ class a host entry of ‘dev-smtp-server’ is applied.

class node_example_com {
    host { “example.com”: ip => ‘10.1.1.1’ }
}

class node_prod {
    include node_example_com
    host { “prod-smtp-server”: ip => ‘10.0.0.254’ }
}

class node_dev {
    include node_example_com
    host { “dev-smtp-server”: ip => ‘10.1.0.254’ }
}

I will then drill down to location starting at the country level. Below are the UK and China classes.

class node_uk {
    host { “uk-gateway”: ip => ‘10.10.10.1’ }
}

class node_cn {
    host { “cn-gateway”: ip => ‘10.20.20.20’ }
}

Once I have country level classes, I define city based location classes.

class node_lon {
    include node_uk
    host { “london-proxy”: ip => ‘10.10.10.254’ }
}

class node_bej {
    include node_cn
    host { “beijing-proxy”: ip => ‘10.20.20.254’ }
}

class node_sha {
    include node_cn
    host { “shanghai-proxy”: ip => ‘10.20.30.254’ }
}

Using the power of puppet, its classes and inheritance with a well thought out server hostname standard from the first day you roll out your startups infrastructure will provide you with much more manageable infrastructure for the future. This should be obvious to any startup who wants to achieve scale.

  • Matt Brown

    Naming servers after their roles is a class mistake that comes back to bite you as soon as you have a hardware failure and have to migrate the functionality to a new host (or parts of the functionality to a few different hosts, etc).

    A far better idea is to name your servers based purely on their physical location, or some other constant factor. Then have a level of indirection (e.g. CNAMEs) to point various services and roles at the host currently performing that role.

  • Anand Kumria

    Umm, it looks like you’ve re-invented puppet’s environment feature but using hostnames.

  • Anand Kumria

    Oh, and in answer to your daylight savings post (apparently comments are off); why aren’t your servers running in UTC?

  • http://twitter.com/ReneCunningham Rene Cunningham

    I choose to use puppet’s environment feature to split manifest that Im currently developing and manifest that has been tested and is running on live nodes. Once manifest has been tested and is considered stable, I move it to the ‘production’ environment.

    As far as I’m aware, you can’t share modules between environments which is why I chose to implement something like this. If I’m wrong, I would take another serious look at environments again.

  • Blinkingeye

    As well as the problem that Matt mentions – there are security implications to naming the server after it’s function. I may well find it very helpful to know that I can direct all my SQL injection “testing” at dev-mysql-server.somedomain.xxx rather than all the other servers on the network. Also labelling prod/dev helps in this scenario as it’s likely to be less well patched or maintained that the prod server.

    I understand the point you were trying to make but 9/10 times I’d recommend using ambiguous names and rely on your knowledge to remember what server does what.

    Also a server called web01.dev.lon.uk.example.com is way less cool than epicservername.example.com ;)

  • http://twitter.com/ReneCunningham Rene Cunningham

    Thanks for the comment. Using non functional server names for the sake of masquerading them from attacks sounds a little bit like “Security through Obscurity” but I do see your point. If someone happened to perform a DNS AXFR of example.com only to see their entire *.prod.example.com environment laid out, that could help with creating an attack vector. Then again, the problem I think that should be addressed is the fact that hostnames are exposed through a DNS AXFR to any server that is not a trusted DNS server.

  • http://michaelhendrickx.com Michael Hendrickx

    I’m with Matt on this, at my company (not really a startup, but a re-implementation of the domain) we named servers based on their function and location.  Any further used names in applications were just CNAMES.

Previous post:

Next post: