a) AWS feature advantages (mostly instascale, in our case) fade with the high cost of every additional dedicated box.
b) It's nice to virtualize the map of services to boxen, but at some level of scale, each box has a single task and you want the ability to run it _flat out_. If so, you have to decide if Xen overhead is worth labor somewhere else, and alternately, if Xen source compatibility holds you back from new kernel features. (Pick your VM technology.)
c) We still wanted instascale with our own software distribution, so in something less than a week I hand-tooled a pxe-based provisioner that initialized from a live exemplar (gentoo, whee). It took some work to find the right propeller heads at Softlayer, but eventually we understood each other and the bootp listeners got turned off for our subnets. "Insta" became 2-hour hardware activation, which was ok for us. You might consider puppet in the same way (except for Gentoo's long from-scratch build time.)
d) Virtually all provider admin is automated and this still works and makes sense at scale. The SOAP API that backs it is not quite fully baked, but is very useful. Paired with box-level IPMI pokes, you can replicate AWS control over hardware.
e) Whatever AWS provides, at scale you still have a custom setup at some level of abstraction, so putting in place exactly the right hardware saves labor.
f) Substantial discounts can be had.