Contents

Puppet type for HTTP Authentication

Contents

I have recently found myself writing a lot of HTTP Authentication password files. After looking around at the various Puppet solutions for managing these files, I wasn’t overly happy with any of them. So I sat down to try to puzzle out how hard it’d be to manage HTTP password files using a custom type. After exploring the htpasswd and htdigest commands it was clear that it wasn’t going to provide a solution: you can add and delete users from files but you can’t query a HTTP password file to determine if a user already exists in the file. This is a bit of a show-stopper with Puppet. To determine what state the resource is in and hence what action to take Puppet needs to be able query whether a configuration item exists or not. I then had a quick look at some Ruby bindings/API for htpasswd provided by the htauth gem but again wasn’t happy with how it was implemented. I also tend to be unhappy with having to install a gem to allow what should be simple code to function. By chance I remembered that WEBrick supports HTTP Basic and Digest Authentication. I knew the support for authentication actions was there but was pleasantly surprised when I discovered that WEBrick could also manage HTTP password files, including adding and deleting users and importantly for writing a Puppet type querying them. The guts of this functionality is provided with WEBrick::HTTPAuth::Htpasswd and WEBrick::HTTPAuth::Htdigest. Naturally, like much of the rest of WEBrick, there is limited documentation and no good examples but it is thankfully a very simple interface. So with some trial and error I have come up with a very basic type and provider that performs some of the same actions as the htpasswd and htdigest commands. You can find the resulting Puppet-httpauth code at GitHub or it’s available as a ready to download module at the Puppet Forge. It’s pretty basic thus far, for example it only creates and deletes users - it can’t check if you only want to change a password rather than create an entirely new user. I’ll perhaps have time to look at that at a later date.