This is interesting, but I find using a different AMI for each project to be tedious. My understanding is that instances should be ephemeral and agnostic to the project at hand. Initial bootstrap scripts should handle the installation of any dependencies and the project code itself.
This setup is very similar to the setup I created at my previous job.<p>Instead of Ansible, I used a plain old shell script, but still idempotent. I did all the testing locally using vagrant/virtualbox. Application deployment was separated in our setup as well, also retrieving the latest application codebase during boot, but using a tgz stored on s3 with the application all the application dependencies (ruby gems and precompiled assets) already in there.<p>All in all I am very happy with this setup being able to autoscale in a few minutes.
Have you looked at docker as a replacement for creating all those AMIs? You could have one AMI (with Docker) installed, and then use Ansible to pull whichever container (app) you want onto each instance.
Using docker also has the added advantage of letting you test your images in the development environment (and it's much faster than vagrant-up for every service you want running locally for dev/test).
The problem I see with using a mostly-baked AMI like this is what happens if your git repo is down when you're trying to bring up a new instance? Bringing up a new server with old code is just asking for all sorts of little problems to spring up if, for example, the git server is down. Given your environment, partial failure seems to be a much worse scenario than an instance not coming up.
I've blogged about a similar exercise here:<p><a href="http://zwischenzugs.wordpress.com/2014/08/09/using-shutit-and-docker-to-play-with-aws-part-one/" rel="nofollow">http://zwischenzugs.wordpress.com/2014/08/09/using-shutit-an...</a><p>This deploys in a reliable way using a docker container and ShutIt, a tool we use in my corp for fast development of reliable and composable iterative steps:<p><a href="http://ianmiell.github.io/shutit/" rel="nofollow">http://ianmiell.github.io/shutit/</a><p>Here's more on the subject:<p><a href="https://github.com/ianmiell/shutit/blob/master/README.md" rel="nofollow">https://github.com/ianmiell/shutit/blob/master/README.md</a>
<a href="https://www.youtube.com/user/ianmiell" rel="nofollow">https://www.youtube.com/user/ianmiell</a>
<a href="http://zwischenzugs.wordpress.com/" rel="nofollow">http://zwischenzugs.wordpress.com/</a>
I'm surprised you use fabric for the last mile instead of ansible. There's really no sequence of run() commands that can't be done better as a quick module.<p>Although I may have been more frustrated than most by paramiko's performance and stability.