I’ve been a puppet user for almost a year, and, after embracing every aspect (as much as I had time for), I’ve learned a few lessons. If you’re just starting out with puppet, skim over the following…
Configuration Management, not Machine Provisioning
Puppet is designed for managing your systems’ configurations across hosts to keep them working the way they are intended to. In this light, Puppet is the tool of choice to manage things like ssh keys, apache configs, or the hosts file. Puppet is not the tool of choice when you’re thinking about provisioning a machine with the push of a button that can install your packages, deploy applications, configure dependencies and create databases. While puppet is very capable at doing these tasks, it requires huge amounts of effort to ensure that all the operations are idempotent. While the button may call a once off bootstrap process, the process must be able to run again and leave the system in the same state. If you try to do this, you’re putting a lot of time and effort into something that is better suited to another tool. Use puppet to manage configurations, not to create a server in a working role from scratch.
Learn the language
Puppet uses an extensive language in it’s manifests which includes things like lists and hashes, automatic documentation, global parameters, parametized classes, node definitions, and more. All of these components help create the core of puppet and gives you power to achieve what you want. In the least, you need to familiarize yourself with what is available, so that when you come to a problem you can recognize the right commands to use. There are a lot of best practices (more) which will help to minimize the time spent restructuring manifests and code when you find an exception to what you think is the best way.
Define relationships explicity
Puppet can be though as a stateful machine where classes are mainly independent. As such, there is no deterministic ordering of when classes are called. This can create issues if you don’t define your class relationships explicity. Defining order will ensure that requirements are met before proceeding onto the next step. There has been a lot of work on this recently, and its definitely worth the time to order your dependencies properly from the start.
Don’t be scared to extend puppet
Puppet is designed to be extensible. It has supporting applications (like mcollective) and built-in plugin architecture which allows for various enhancements. You can create your own system to tell puppet which manifest or classes a node should get based on whatever parameters you want by developing your own node classifier. You can create functions which can be used within manifests to modify variables, or fetch information. You can create your own resource types to handle a custom resource in the way you want it handled. What’s great is that none of this development is particularly difficult, and the information is available. There are also 3rd party extensions available, so be sure to search to find out if anyone has already done what you’re looking to do.
Read blogs, get involved
The puppet community is very friendly and helpful. A lot of the best puppet ideas have come from blogs from people talking about how they configured puppet to achieve their goal. Chances are that your organization will find familiarity with some of these patterns. Don’t spend time designing your own pattern when there is already one available that solves for your system. There is a caveat to this though, don’t use someone else’s pattern unless you know it will suit you. Restructuring puppet manifests is slow and you don’t want to be there if you don’t have to be. Find puppet users on twitter, sign up for the puppet mailing list, join #puppet on irc, read blogs.
Separate data from code
Puppet has data, like the ip address of your load balancer for example. You could include data straight in your manifests, but, this would be a mistake. Separate your code from your data. Currently, ext-lookup is a good solution for this, but I believe puppet is looking at restructuring the way code and data and separated, so keep a lookout on the best practice for this.
Document your manifests
Puppet has built in documentation generation. Use it. Six months down the line when someone is trying to figure out where a manifest is used, or what the class parameters do, it sucks having to read the class and follow custom definitions or types, work out what variables are used or even where they come from. Document your manifests with who wrote the class, parameters used, summary, externally sourced parameters, and so on.
Missed anything, let me know… @nuknad on twitter, or comment