Because SSH and “for” loop doesn’t cut it
Posted on November 15, 2011Here at Tuenti we were managing our servers in a old-fashioned way for a long time. We used “for” loops in order to replicate changes across different servers, but as we’re grew that became more complex over time and with new people joining the team. Fortunately, now we have an automated deployment system that deploys a basic image to a server based in its server role. Once the node is up we use Puppet for transforming the node to the desired state, ensuring specific versions of the packages are installed, configuration files are in place and services are running.
We have chosen Puppet because it’s easy to understand, it’s straightforward, it’s extensible and it has a very good community around it.
- Easy to understand: Puppet doesn’t have obscure components that are hard to understand. For example, the communication between client and server is made using a REST API over a SSL channel using client certificates issued by the integrated Puppet CA.
- Straightforward: Moving from manual configuration to configuration management system requires a change of mind about how you manage your platform. Nevertheless, you’ll be able to deploy it and write your automated configurations in minutes. People in the team was able to configure new components and modify existing ones after a brief explanation.
- Extensible: At the moment we just created custom facters, but we’ll need to extend puppet with custom types for easily managing our queue system configurations in a more flexible way. Some people have started to share some custom types and modules in the Puppet Module Forge.
- Community: I had the pleasure of attending last PuppetCamp Europe 2011 held in Amsterdam on April 28th. I have met and shared experiences with a lot of developers, people working in systems operations, and even the PuppetLabs engineers. In the open conferences, the strong technical background of the attendees was apparent and you could see how PuppetLabs engineers listened to us about which features we would like to have in Puppet or how to improve them.
When we configure the amount of PHP processes that we spawn in our frontends we base this decision on the amount of CPU power of the server. This has a direct relation with the amount of memory, given that more CPU means more concurrent requests and also more memory usage. For automating the amount of PHP children that should be spawned we use a custom facter. A custom facter is a piece of Ruby code that is executed to return a fact for a node. The default facts are hostname, ip address, netmask, amount of memory, processors, kernel version, etc, and they’re very useful, but sometimes you need to extend it. In the example displayed below we create a custom fact called “tuenti_phpchildren” that will take decisions about the amount of PHP children spawned per server. I use an existing custom facter called “tuenti_memorysize” that returns the amount of memory installed in a server as an integer.
Facter.add("tuenti_phpchildren") do
setcode do
memtotal = Facter.value('tuenti_memorysize')
if memtotal > 20000000
phpchildren = "300"
elsif memtotal > 9000000
phpchildren = "200"
elsif memtotal > 5000000
phpchildren = "100"
else
phpchildren = "50"
end
phpchildren
end
end
Then we use the custom facter inside a template, to ensure the file contains the proper configuration for the daemon.
max_children = <%= tuenti_phpchildren %>
Automating your whole platform using Puppet is not something you’ll accomplish in three days (if you have a large fleet of servers with different roles as we have), but it’s a really worth the effort. Some advantages we got from moving our configuration management to Puppet are:
- No configuration drifts: Puppet is checking in the background that everything is fine and will revert to the desired state if something has changed (accidentally or on purpose).
- Become more agile: We are a fast-moving company that requires changes every day and we can’t continuously spend our time on repetitive tasks. Now we deploy changes to production within minutes having more control than we use to have in the past.
- Save time: We automate once and we could be able to easily bootstrap hundreds of nodes in minutes.
- Comply with industry standards: Some law enforcements like Spanish LOPD or PCI Compliance require a list of policies that must be met in all the servers from your company, like access controls, encryption ciphers used in SSL transactions, password management and more.
- Document itself: Puppet won’t excuse you from documenting your platform, but once someone reads a manifest they’ll already understand what that piece of code is doing. No more tedious explanations about what to do or what to execute for configuring a service.
- Share knowledge: Now we’re able to share our Puppet modules with other teams like QA or Dev Tools in order to align our development, testing, and production environments. Also, using different Puppet environments we can have different versions of a module in different stages like development, staging and production, while having a reasonable workflow: First you develop it, then you try it across some servers, and finally you deploy it to the whole platform.
Our current Puppet architecture is based in three Puppet Masters that bring configuration management to more than 1k nodes. Scaling this platform is as easy for us as adding extra nodes and adding them to the load balancing pool. Puppet also offers a reporting feature that can be used with the Puppet Dashboard in order to have a view at a glance of your platform. Given that all the reporting data is stored in a database you can integrate it with your internal tools or dashboard in order to detect nodes that are not applying configuration properly or are suffering unexpected changes.
To make the development of manifests easier, a project named Geppetto was born some time ago. Besides the tool itself, it offers a module for Eclipse that will make your life much easier. For hardcore people, you also have Vim syntax highlighting provided by PuppetLabs.
In summary, even if you only have one server you need to be able to reproduce its configuration. So if you have the opportunity, try some configuration management like Puppet and move out from sysadmin hell to operational bliss.






November 22, 2011 at 3:01 pm
Hi,
happy to know firms like you are using Puppet. We’ve been using it for a while too, having migrated from cfengine. We were using it only for our sake, to make our job easier, but now we’ll be able to add it to our “features” saying that “it’s what they use at Tuenti”
I’ve got a few questions about your setup. I hope they’re not all covered by some kind of NDA
Thanks in advance.
1) What version of puppet are you using? Is it the same across all the servers, or are you mixing old (i.e., 0.25.x) and new (2.6.x) versions? It looks like a silly question, but we have servers with somewhat outdates distros where we have to resort to old releases.
2) You mention Puppet Dashboard. Is that what you use? Did you check Foreman? If so, and it was discarded, why?
3) Do you store the host configuration in LDAP, or use a plain “nodes.pp” kind of file? (I guess the former, but ask just in case)
4) This is not really related to Puppet, but anyway: what do you use for bootstrapping servers? I.e., some known product (like Cobbler), or a custom development?
I think that’s all good manners allow me to ask without feeling obnoxious
Thanks!
November 22, 2011 at 3:34 pm
Very interesting Ricardo! It´s interesting how do you manage to perform a bunch of changes on hundreds of machines!
Thank you!
November 28, 2011 at 2:14 pm
Hello Roberto,
In our case this was our first iteration over a configuration management application, and we’re really happy with Puppet. Regarding to your questions:
1) We’re using 2.6.x and we’re planning a upgrade to 2.7.x. We usually make backports of newer versions in order not to suffer the problems you describe. In the case of Puppet, the only requirement is ruby and some gems.
2) We only use Puppet Dashboard as console in order to have a view at glance of the configuration status, with nodes have failed applying catalogs, etc. Some features like external categorization are not used at the moment, but we’re really looking forward for the remote filebucket diff feature included in Puppet 2.6.x and Dashboard 1.2. We’ve checked Foreman in the past, but what we needed was something small, like Dashboard. Is true that Puppet community widely uses Foreman for reporting and node categorization and we don’t discard using it in the future.
3) We are using plain nodes.pp for server categorization and class assignation. We match servers with node classes using regular expressions so we don’t need to regulary update the files.
4) At the moment we’re using a combination of both PXE images and internal-developed tool. Nevertheless, we will try to move all this to Cobbler or a similar solution in the upcoming months.
Regards,