Load a Grails or Java application to Elastic Beanstalk on AWS
What you will learn here:
- How to create and configure the Elastic Beanstalk container.
- How to create and configure a MySQL relational database service.
- How to create and configure the Route 53 Domain Name Service to be used by your application.
- How to migrate existing data to the database in the second point above, if neccessary.
- How to set up your application to use the database in the second point above.
- How to load your application to the Elastic Beanstalk container.
About AWS
Amazon Web Services is a product of the online store, Amazon.com which used to be an online bookstore only. As possibly the biggest online store, they have a huge IT infra structure. This is what they've made available to anyone needing IT infra structure. Of course, they've most likely adapted and added to what they themselves use.
AWS's offerings are available as modules which can be set up to interact with each other. AWS calls these modules services. The glue which links one service to another is a Security Group. You open up a service to another service by creating a security rule in the security group of the target service, allowing in the security group of the originating or accessing service. An example is your relational database service which is accessed by your web application.
Keep in mind that we are only interested in a small subset of the AWS services; hardware resources to run an operating system which will run Tomcat to which we will deploy our Grails application. We also need a relational database and networking resources to link our domain name to our Grails application.
The virtual server with the operating system is called EC2 - Elastic Compute Cloud. You will get your own EC2 instance and you can install all software you want to on it. You will be able to SSH into this EC2 instance. As the need for running a web application is so common, AWS has a template which will add some of their offerings - those needed to run a web application - to EC2. The resultant offering, or service in AWS speak, is called Elastic Beanstalk. If you create everything, including the relational database service, in Elastic Beanstalk, then the security groups are created and wired for you.
The relationa database service (RDS) is a managed service running in its own virtual server with its own CPU and memory resources. As AWS manages this for you, you have access to the database but not to the virtual server on which the database runs. For the first year a T2Micro instance of the RDS is free. Thereafter the price is slightly higher than for a EC2 service. 1.7c/hour for a T2Micro RDS service vs 1.3c/hour for a T2Micro EC2 service in the US East region.
You can install a database server in your EC2 service and use that. That will share resources, like memory and CPU, with your EC2 instance and won't cost you extra. But you are then in charge of that - no back-ups, no automatic updates, data lost when your EC2 instance terminates, etc.
One of the worst things of AWS is its naming conventions. You will find a My First Elastic Beanstalk Application in your Elastic Beanstalk dashboard. It's not an application in the usual sense, at all. It's more like a blueprint of your Elastic Beanstalk specifications. Under that you will find a Default-Environment which is really an instance of your My First Elastic Beanstalk Application. You actually deploy your Grails application to your Elastic Beanstalk Environment, in this case named Default-Environment. Go figure. It's not the only case of confusing names in AWS.
AWS is changing quite rapidly, and for the better. It's getting easier to manage and their offerings are getting more powerful. Even the free offering. It used to be imperative to create swap space to compensate for the marginal memory allocation of the free offering when deploying a Grails application. It may still be a good idea to configure swap space, but no longer is imperative. What is below will show you how to create the new T2 EC2 instance and a T2 database. The only significant difference in setting this up, as compared to the previous T1 offerings, is getting your application running in the Elastic Beanstalk container to use your database.
Sign up for Amazon Web Services
That you can do here. You can sign up for the AWS Free Usage Tier which will give you 1GB of RAM, enough for a modest to average Grails application. Jump through all the hoops to get your account verified and going.
Log in to your Amazon Web Services account
Go to the
ASW Management Console
if you're not already there. It used to look somewhat like this:
Now it's different. Even so, you will easily be able to follow along. The Services menu item is still at the top. From it you can easily access any service mentioned. Once on the page of the specific service, things will again look much like the screen shots below. We are going to use the following services in the following sequence:
- The Elastic Beanstalk icon which leads to the Elastic Beanstalk dashboard
- The EC2 icon
- The RDS icon
- The Route 53 icon
Create your Elastic Beanstalk container
Click on the Elastic Beanstalk icon which will take you to the Elastic Beanstalk Dashboard
which looks about like this:
Make sure you select the same geographic area at the top right side for everything from now on.
Choose your container - Tomcat - and your Java version. Click "Launch Now" button.
When things settle down you'll see:
The sample application is now running. We're later going to overwrite that with your own application. But before we get there we've a few things to do.
Configuring your Elastic Beanstalk container
Now click the "Configuration" link on the left. You will be taken to a screen looking much like:
You will never use the "You do not have a database. You can create a new RDS database or use an
existing database." at the bottom
of this page. When I used it, it tried to create me an old T1 database instance.
Update: this may no longer be true and you may be able to create the database here.
In that case the security group will be created for the rds instance and wired to your
EC2 instance which has been configured to be an Elastic Beanstalk instance. Think of
Elastic Beanstalk as being EC2++.
Now click the gear icon next to the "Softw/are Configuration" heading.
Change the Java configuration to values that will be adequate to run your application.
The default values will give you "out of memory" errors.
Click "Save" and wait for things to settle down.
Now you have to create a key pair which you will use to SSH into your running EC2 instance.
You also have to associate this key pair with your running Elastic Beanstalk instance, which will,
behind the scences, associate it with the backing EC2 instance.
Use the "Services" menu item to get to the EC2 dashboard.
You will come to a page looking like this:
Select the Key Pairs option under Network & Security on the left. You will come to a page looking like this:
Now create a key pair and download the one to your computer. You have to change it's
permissions: $ chmod 400 mypair.pem. This is for Linux. I have no idea what you
do on Windows. You can now use this key to ssh (PuTTY on Windows) into your machine
running your Elastic Beanstalk - more on that later.
Use the "Services" menu item to get back to the Elastic Beanstalk dashboard.
Now click the "Default-Environment" link in the green area. On the next screen
click the "Configuration" link on the left side.
Click on the gear icon next to "Instances".
You will come to a page looking like this:
Now select your key pair from the drop-down list and click "Save". The key pair you created
before is now associated with your Elastic Beanstalk container and can be used to log into it.
You really log into a Linux operating system. It's the Amazon version of CentOS. The next few paragraphs
explain how to do that. Also make very sure that you selected a T2 Micro instance.
Click "Save". You will get this warning:
Click "Save" again.
First, one must make sure port 22 is open to accept connections from the outside - i.e. from your machine at
home or at work. So, use the "Services" menu item and then the "EC2" icon. On the left
side, find and click the "Security Groups" link. Tick the "SecurityGroup for
ElasticBeanstalk environment" tickbox and see if port 22 is open as indicated on the image below. If
not, create a "SSH rule" to have it open and available. You have to click the
"Actions" tab and then the "Edit inbound rules" item as shown below:
As you can see from the next image, I limited access to my own IP address:
It goes without saying that you should click the "Save" button.
Still on the "EC2 Dashboard" you can now click the "Instances" link on the left side.
The page, after selecting the one instance on it, will look something like this:
What you want is the "Public DNS" You can also click the "Connect" tab at
the top and you will get the actual IP Address to connect to.
All you need to do now is open a term window, migrate to the directory where you have one of your key pair and, using the public DNS obtianed above, do:
$ ssh -i ./mykey.pem ec2-user@ec2-87-215-167-170.compute-1.amazonaws.com
The ec2-user has been created for you and you need to type it in as shown. You will be logged in on a page looking much like this:<
Last login: Wed Jan 1 17:49:17 2014 from ppp121-44-222-198.lns20.syd6.internode.on.net __| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2013.09-release-notes/ [ec2-user@ip-183-44-40-57 ~]$
That's it. Next we create your database.
Creating your database
Use the "Services" menu item and then the "RDS" icon. You will see a page like below:
Click the "Get Started Now" button. You're now in a web flow which will take you from page to page.
Configuring your MySQL database instance
You should now be in "Step 1" looking like this:
Select the "MySQL Community Edition" database.
"Step 2" looks like this:
Be sure not to choose "Multi-AZ Deployment" if you want to be eligible for the
"Free usage tier."
"Step 3" looks like this:
Look at the values in the image and select much the same. Make sure you select a T2 instance.
"Step 4" is the last of these web flow steps and looks like this:
Be sure to enter a database name otherwise a database won't be created for you. When the database
has been created you can click "View Your DB Instances" You'll be taken to a page looking like this:
Select the newly created instance of your database. You will notice in red "No Inbound Permissions".
You can set up the password by clicking "Instance Actions" and then "Modify".
Making your database available
Use the "Services" menu item and then the "EC2" icon. You will be taken to the page
below. Click the "Security Groups" link on the left. You will notice three security groups.
There is one for the Elastic Beanstalk environment and one which description starts with
"Elastic Beanstalk created security group used..." This is the one you're interested in.
Now create a "MySQL rule" in this security group. The default listening port is 3306. This is
for connections from your application running in the Elastic Beanstalk container.
Use the "Group ID" of the Elastic Beanstalk security group as the source for the connection.
You can also create a connection from the outside - i.e. your computer at home or at your work.
Use your IP Address or a mask which you can get from your ISP which will cover all IP addresses they may
asign to you. This way you don't have your database open to traffic from everywhere.
Here is what it looks like when all connections have been set up:
Now, again, use the "Services" menu item and then the "RDS" icon. Click the
"Instances" link on the left side and you will be on a page looking like this:
You will see that the red "No Inbound Permissions" is now gone. Make a note of the
"Endpoint" and "DB Name" The database name will be the one you chose. You can now open a
term window and, using the endpoint which you noted, do the following:
chris@mercurius:~$ mysql -u yourdbuser -h ad2pqrs13o0dbj8.cbei2knihvtv.us-east-1.rds.amazonaws.com -P 3306 -p your_db_name Enter password: type in your password and press enter and you will see the folowing: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1918 Server version: 5.5.33-log Source distribution Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
If you type in show tables; and press enter you will see that there are no tables in your database. You can now close the connection to your database by typing in \q and pressing enter.
Migrating your database
If you don't need or want to do this, you can skip this heading. Otherwise, open a term window, migrate to where your MySQL database dumpfile is, let's say dumpfile.sql, and enter the following:
chris@mercurius:~$ mysql -u yourdbuser -h ad2pqrs13o0dbj8.cbei2knihvtv.us-east-1.rds.amazonaws.com -P 3306 -p your_db_name < dumpfile.sql
You will be prompted for a password, like before, and then your database structure will be created and your contents migrated over to AWS. This will take some time. When you see the normal local prompt again you can log in to your database like before. show tables; this time should show your new tables. Queries will reveal the content in your new tables.
Your Grails DataSource.groovy file
In Grails 3 it's application.yml. The sytax is different, but easily understandable. The data that goes into it is much the same as shown below. You already have all the details for this. Without further ado, this is how DataSource.groovy should look:
production { dataSource { pooled = true dbCreate = "update" driverClassName = "com.mysql.jdbc.Driver" username = "yourdbuser" password = "yourdbpassword" url = "jdbc:mysql://ab2pqrs13o0vaj8.cbei2knihvtv.us-east-1.rds.amazonaws.com:3306/ebdb" dialect = org.hibernate.dialect.MySQL5InnoDBDialect properties { validationQuery = "SELECT 1" testOnBorrow = true testOnReturn = true testWhileIdle = true timeBetweenEvictionRunsMillis = 1000 * 60 * 30 numTestsPerEvictionRun = 3 minEvictableIdleTimeMillis = 1000 * 60 * 30 } } }
Now create your war file. For Grails it's: grails prod war
Uploading your application war file
Go to the "Elastic Beanstalk Dashboard" by the by now well trodden road
of the "Services" menu item, then the "Elastic Beanstalk"
icon and then the "Default-Environment" link on the green background. You should see the
page below:
Click the "Upload and Deploy" button. Now click the "Applications Versions page" link,
which is shown in the following image:
You will end up on a page like this:
Now load the war from your machine. Understandably, this will take a while. When that's done, deploy it.
When all's said and done and you go back to the Elastic Beanstalk Default Environment page you should have
the white tick on the the green background and your application's name should be under
"Running Version" where it used to say "Sample Application", like below:
OK, so there's no stopping you now - you want to see your application running on AWS in all its glory.
Go to the "EC2" dashboard through the by now familiar "Services" menu item,
then the "EC2" icon. Click the "Load Balancers" link on the left. Tick the load balancer
tick box and you will see the following page:
What you're interested in is the "DNS Name", shown white on a blue background. To the right of it,
it says "(A Record)" Copy and paste that to a browser address field and voila, your application in
all its glory. Now isn't that neat?
Now if it's not so neat and things don't work, you'll have to go to the "Elastic Beanstalk" dashboard and click the "Default-Instance" link and from there the "Logs" link on the left. Then you'll have to look at the logs and try to figure out what went wrong and fix that.
All that now remains is to get your application when someone types https://www.yoursite.com in a browser address field. Hang on, the end is in sight.
The Route 53 Domain Name Service
As the name says, this is a domain name service. In short, you have to tell your domain name registrar that the "Route 53" service you're going to create now is your domain name service and all requests for your domain name should be directed here. Then you're going to tell the "Route 53" service you're going to create now to direct all requests for your domain name to the application you've loaded just now - that's with and without the www.
By now you know how to get to a dashboard. It's the "Services" menu item, then the
"Route 53" icon.
You may get to this:
If so, click the "Get Started Now" button under "DNS Management"
The dashboad will look much like this:
Click the "Create Hosted Zone" button at the top. On the right side of the page a form
will appear into which you have to write the domain name you want to resolve to your application, e.g. mysite.com.
After doing that click the "Create" below it.
You will now be on a page looking like this:
Make a note of the "Name Servers *:" highlighted in blue in the above image.
The next thing you have to do is to create a record set for your new hosted zone. You really have to create only two
record sets, one without and one with www for your domain. Both will be A type Alias records. Click the
"Go to Record Sets" button as shown on the image above. You will now end up on a page like this:
Click the "Create Record Set" button. This is what you will see:
On the "Alias Target" drop down list you will see only one known value, that for the
"Elastic Load Balancer". That is the same value as the "DNS Name" you used
before to get at your application. Select that. Do not fill in any IP address here. Route 53 uses
this "DNS Name" to get the IP address. You have to go through this twice, once with
mysite.com and once with www.mysite.com, that's if you want both of those typed
into a browser addres field to lead to your application. This is what the page looks like when you're finished.
You will see four DNS addresses on the image above. Your values will most likely be different.
Go to your domain name registrar and change the DNS adresses to the ones you have corresponding to
those in the image above. Now you have to wait some time, 30 minutes to some hours. Then your
application running on Elastic Beanstalk should be available to the world at your domain name.
If you find what you learned on this page useful, please use the social media widgets at the bottom and pin, tweet, plus-one or whatever this page.
Write a note to let us know what you think of all this.
Use and empty line to separate paragraphs in the "Comment" text area.
Links and html markup are not allowed.