In addition, I allocate the workers to their own instances so that they can grow independently. Also I use Capistrano to automate deployment. Whenever additional resources are needed, simply clone the instance and add it to the load balancer.
I use 2 Nginx workers and 8 Unicorn workers in a single app instance, and they serve in HTTP at 80 and 443 (yes they respond in HTTP via port 443 and the app should assume it's HTTPS). The app instances are firewalled in a private network and they use private IP addresses.
The load balancer has two networking interfaces, one public-facing and one private-facing. It's basically a reverse proxy serving traffic in both HTTP and HTTPS (which will be forwarded to HTTP:443). So the load balancer handles the encryption entirely.
The assets get compiled during deployment, and everything gets cached. I bundle all the CSS and JS into a single package, so that there's nothing to load other than the HTML and images (natively async) in subsequent visits. The website is simply way more responsive when deployed this way. I also use CloudFront to host the assets by simply pointing the cloud distribution to the website itself as the origin. Rails will handle the assets host automatically as well.
Whenever I need to deploy or manage the database directly for any reason, I will need to connect to the private network via VPN. It's secure and just neat.
If I need to build a local mirror, I'll install another nginx box, connect to the VPN, and reverse proxy HTTPS requests to the HTTP:443 directly. This reduces the HTTPS handshaking latency while still maintaining the security. And it just works.
EDIT: Added a link to make it easier for the curious people.