Currently, our deploys are managed by a combination of fabric (the Python shell automation toolkit) and puppet. Puppet ensures our servers are fully configured, fabric orchestrates everything. We also have a Jenkins CI server which can be used to deploy at the click of a button, rather than running a command-line script.
We can deploy to different environments or using different code branches using command-line arguments. For example:
$ fab e:live deploy
Deploys our 'master' branch to our live environment. $ fab e:staging target:feature/new-login deploy
Deploys the feature/new-login git branch to our staging servers."target" can take anything Git can - a branch, a tag or even a commit hash.
We use south to manage our database migrations, which run as part of the deploy. Our static CSS/JS/etc assets are hosted on S3, and have their filenames rewritten to include the hash of the file contents before being uploaded - that way we can push new assets to S3 without overwriting the old ones, meaning that we don't have to worry about keeping our asset deploys perfectly synced with rolling out new HTML templates (which may depend on new CSS etc). We push new assets automatically at the start of the deploy.
It works pretty well so far; we'll almost certainly be looking at ways to make it easier as it's currently a rather lengthy knife command.
Fabric logs into the servers and issue chef-client-command.
Chef does currently only handle the deployment part, ie pulls new code from git and refresh the app-server. I'm looking into setting up a cookbook that would be able to take a bare cloudserver and put it into production with the webapp running on it. That way I could scale faster if I would get unexpected traffic.
It's just:
git push heroku master