AWS Beanstalk and more

While playing around with AWS Beanstack (EB) and related infrastructure, found out couple of thins that want to note for future reference.

Initial scenario: AWS Beanstalk environment in a private subnet, with AWS LoadBalancer (LB) serving requests and doing SSL termination. No need to do end-to-end SSL as actual EC2 instances are in private subnet. Also need to redirect HTTP to HTTPs, preferably on load balancer level.

 

So we first we need to create a VPC, Internet Gateway a some subnets. I have one public subnet (local routes + default via Internet GW) for service things like NAT gateways, bastion hosts, etc, two private subnets (local traffic only) for web instances (in different AZ) and two public subnets for load balancers.

Here come few first notes:

  • two have EC2 Instances of web servers in private subnet, you need to have LB in public subnet.
  • private subnets with EC2 Instances should have a routing table with default route to NAT Gateway, which MUST be in a public subnet (either along with LB or separate service subnet)
  • VPC MUST have DNS resolution and DNS hostnames set to YES

The above is more or less enough to start with EB, as it will create bunch of staff for you automatically (or you can find a way to mess around with plenty of things).

For EB:

  • Make sure the EB environment is linked to appropriate VPC before you start checking other settings, as this is what brings all those subnets, security groups and other options in.
  • User multi-instance setup with LB even if you plan to have only single instance. Just set the auto scaling max to 1, but this will give you bunch of options and flexibility later on.
  • Use Application LB instead of Classic one
  • Use your proper Key-Pair for EC2 instances in Security section as it will give you a chance to SSH to instances to troubleshot in case of problems (via bastion host or by temporarily making web subnet public and attaching elastic IP to instance)
  • Modify webroot in software configuration in case your project is not served directly from root of the project (/public, /webroot, etc)
  • Utilize Environment Variables for passing info about DB settings, DEBUG, etc, if your application supports it. Very handy.
  • Use Amazon Certificate Manager + Route53 for issuing and renewing SSL certificates that you can attach to LB.
  • Make sure you have both listeners in LB setup: for HTTP and HTTPs

When you environment is up and running, there are couple of things to adjust:

  • CNAME you environment domain to EB entrypoint domain
  • In EC2, Modify rule for EB Listener that is working on port 80 and add a rule on top of default one to redirect to HTTPS (same origin, path, args) when Path is *
  • In case you app uses full URLs, you may have a problem that it sends links in HTTP. In my case I am passing BASE_URL env var to the environment of the EC2 instances and my app picks it up from there and returns correct links and refs to other resources like JS & CSS.

This is just a short list of things to keep in mind. More things might come and most should go to AWS CloudFormation, but I had to play around via AWS Management Console manually first to get the feeling of the service.