I'm trying to get my head around a simple WebApp Java deployment case on Amazon Web Services.
I have manually deployed on a single EC2 instance, manually installing Java, Tomcat, MySql on a vanilla RedHat image -- as if I owned the hardware.
Now I'm trying to set up an auto scalable, easy-to-manage, production proof environment:
- 1 -> n Tomcat instances with a standard Java WebApp deployed,
- 1 MYSQL database with 1 schema and a few tables (not much), the webapp connects to it.
I understand that autoscaling depends on some trigger (e.g. more than % of usage). However, when the new server is started, my app is not deployed because it's not in the VM image. Something needs to happen so that the new servers run my code.
- What is the best option to mass deploy to 1-n autoscaling group of tomcat only servers on amazon?
- What is the best option to upgrade your app ? I guess you don't want all the servers to go down in one go...
- How about creating a VM image that automatically retrieves the latest build available from my CI (uploaded to a S3 or something else)? I could easily add this script to Tomcat bootstrap / linux startup...
How about commercial tools like Chef or Puppet? Any open-source equivalent?
I reviewed a lot of things on the web and yes, ElasticBeanStalk is the right thing to use as Georges said. Though, it feels like it's quite confusing at start.
First of all, you can run a load balanced / scalable environment on the Free tier using t2.micro instances. What matters is the number of hours in total. You can use 100 servers for 7 hours and it'll be fine. Be careful with Health Check because it pings your environnement all the time. If you run tests / evaluation and don't want to pay, make sure you save / backup and terminate your environment as soon as possible. Data Transfer is not free of charge apparently so make sure you don't use any multi-AZ and multi-zones if you don't want to pay.
That said, BeanStalk is a kind of "black box" that does a lot for you. It is intended to create all the configuration in the console for you. A kind of "super-wizard" for load balanced / scalable environments.
Configuration goes like this : you say you have a war file you want to deploy, you upload it, you pick a container (e.g. linux+tomcat), you set up a database and it will create a basic configuration with all you want : Load Balancing, autoscaling and monitoring. It's easy to change to settings to match your needs.
One tricky thing is database configuration : you need to set environnement variables and use them in your spring configuration as per : https://raymondhlee.wordpress.com/2013/06/01/migrating-a-java-web-app-for-deploy-to-aws-elastic-beanstalk/
Application update can occur in "rolling way" i.e. occurring on limited percentage of your fleet of servers (default is 30%) which means you don't have to worry too much about downtime.
Boxfuse does what you want.
For you Java web application you literally only have to execute:
boxfuse create my-tomcat-app -apptype=load-balanced
boxfuse scale my-tomcat-app -capacity=1-16:t2-micro:cpu25-75
boxfuse run my-tomcat-app-1.0.war -env=prod
This will
- Configure your application to use an ELB
- Set it to autoscale between 1 and 16 t2.micro instances based on CPU usage (scale in at 25% and below, scale out at 75% and above)
- Create AMI with your app and Tomcat set up so they are ready to boot
- Create an ELB
- Create a security group with the correct ports
- Create an auto-scaling group
- Launch your instance(s)
Any subsequent update will be done as a zero downtime blue/green deployment.
More info: https://boxfuse.com/blog/auto-scaling
You could make use of the User Data on an EC2 launch configuration. You can use this to pass a shell script to your instance that will run automatically when it is launched for the first time. A common pattern is to have the shell script download and install a build from S3, as you suggested in your question.
With this pattern, upgrading the build on your auto-scaling group is easy. Simply upload a new build to S3. Then, manually terminate instances in the auto-scaling group. The auto-scaling will automatically spin up new EC2 instances, which will download the new build from S3, and presto, your auto-scaling group is updated. If you terminate each instance one at a time, and wait for the new instance to come online before terminating the next one, the impact on your system is minimized.