Using S3 as a cookbook store backend for chef-server 11

chef-server is a modular service - various tasks are delegated to different sub-services, one of which is Bookshelf, Chef’s cookbook store in charge of storing and serving cookbook files. Bookshelf’s API is S3 compatible by design (I can only assume Opscode are using S3 for their SAAS) and can be replaced with S3. Using S3 as the backend store makes sense for clustering, but there’s very little information on the web on how to configure chef-server to use it. Luckily, the configuration is not very complex.

Create a new S3 bucket for Chef cookbooks and a new IAM user for Chef server. Give the new IAM user permissions for the bucket with a policy like this one:

{
  "Statement": [
    {
      "Action": [
        "s3:*"
      ],
      "Resource": [
        "arn:aws:s3:::my-bookshelf-bucket/*"
      ],
      "Effect": "Allow"
    }
  ]
}

Install chef-server as usual from the Omnibus package, then edit /etc/chef-server/chef-server.rb:

bookshelf['enable'] = false # we don't need the bookshelf service anymore
bookshelf['url'] = "https://s3.amazonaws.com"
bookshelf['access_key_id'] = 'AKIAIAUEDF124NTFAUQ'
bookshelf['secret_access_key'] = 'Ko+L40eraJAlskjdfabBa212VAasdfBAAKRL'
erchef['s3_bucket'] = 'my-bookshelf-bucket'

The access_key_id and secret_access_key are the credentials you got for the new IAM user. Now run chef-server-ctl reconfigure (as root) and viola!!

Note: If you already configured chef server once you need to remove the old s3 keys from /etc/chef-server/chef-server-secrets.json before running chef-server-ctl reconfigure

Warning: If you previously uploaded cookbooks to this server you must sync bookshelf to your new S3 bucket. you can do this using any S3 client library. If you don’t sync, Chef’s cookbook metadata will be out of sync and you will be in a world of pain. The symptoms will be chef-client not being able to find cookbook files and knife cookbook upload won’t upload the files since it figures they are already in bookshelf.