Introduction
Welcome back. In Part I
of our tutorial, we took steps to deploy a MEAN application to EC2. In
the process, we created a running EC2 instance, configured our security
settings, made a connection, and set our application to run.
- Part I: Getting Started and Deploying your Initial Application
- Part II: Utilizing your EC2 Instance of Mongodb
In this part of the tutorial, we’ll be modifying our MEAN application
to utilize an instance of MongoDB running on our EC2 server.
Why should we do this?

As we discussed at the conclusion of Part I, our current
To-Do application is relying on an external instance of MongoDB. Specifically, we’re employing a Database-as-a-service (DaaS) offered by
Modulus.io to provide a complete database that our node application can connect to.
DaaS’s (like Modulus.io,
MongoLab, and
Compose.io)
offer a convenient way to use MongoDB without having to handle
installation and troubleshooting. As an added advantage, they often
provide friendly GUIs for administering and querying their databases.

That said, these services come with tradeoffs.
For one, their monthly cost tends to be significantly higher than if
you setup MongoDB yourself on your own server. As an example, an M1
Cluster with 40 GB of storage would cost you about
$180 per month using MongoLab. In contrast, a similar MongoDB instance in EC2 would cost only
$36 per month if you set it up yourself.
Additionally, using DaaS’s often limit your ability to fully
customize all aspects of your database. (If, for instance, you were
creating a healthcare application and needed a HIPPA compliant system, a
ready-made solution
typically wouldn’t make the cut.)
Just consider the pros and cons. But for today’s tutorial, we’re
going to ditch the DaaS in favor of our own EC2 instance of MongoDB.
Getting Back to Business
Because this tutorial is focused on deployment, you will need to have
completed Part I in order to follow along. Take a look and come back
when you’re done. For those returning, make sure you have your passwords
and account details handy.
Once you’re ready, let’s connect to our EC2 instance again using PuTTY.

When prompted, enter:
bitnami to login.
Logging into MongoDB
To begin working with Mongo, we’ll need to login as an administrator.
Here, we’ll be making use of the green password we obtained in Part
I. (Remember, that password is only displayed once. If you failed to
record it earlier, you’ll need to create a new EC2 instance and repeat
Part I again. Sorry!).

While in the EC2 terminal, use
mongo admin to enter MongoDB. (p.s. Remember to include
sudo or you may go crazy wondering why MongoDB refuses to permit you):
sudo mongo admin --username root --password {YOUR GREEN PASSWORD}
Once you’ve logged in, the first action we’ll take is to create a new
user with administrative privileges. We’ll create this account, so you
have access to a username and password you can actually remember.
> show dbs
> use admin
> db.createUser
> db.createUser(
{
user: "YOUR USERNAME",
pwd: "YOUR PASSWORD",
roles: [ "root" ]
}
)
If all goes well, you should be notified that the user was successfully added.
Now, log out of mongodb by entering
ctrl+c and try logging back in using your new admin username and password.
sudo mongo admin --username {YOUR USERNAME} --password {YOUR PASSWORD}

Confirm that your account has been granted complete privileges by
querying the databases and adding in a dummy record. Here we’ll add a
record: “This is a test” into the “test” collection of “dummyDB”.
> show dbs
> use dummyDB
> db.test.insert({ item: "This is a test"})
If we query for the record we should see it appear.
> db.test.find().pretty()

Perfect. There’s our dummy record — proving that our admin account is fully functional. Now its time to connect our app.
Enabling Access
Before we can copy and paste our MongoDB URL into our MEAN
application, we need to make sure that its fully accessible. This means
two things. First, it means ensuring the MongoDB port is accessible to
the outside world. And secondly, it means configuring MongoDB so it
knows which IP addresses to allow database access.
We aren’t going to dive too deeply into “ideal” security settings in
this tutorial. How loosely or how tightly you need your database access
to be is dependent on your specific application. And since we’re just
deploying a simple demo, we’re going to keep things simple.
So let’s begin. For a first step, let’s make sure the MongoDB port is
accessible. We cheated and already did this in Part I, but I think its
worth re-examining. By default, the port used by MongoDB is 27017. (The
Bitnami image we used in Part I also uses this default as well.)
Now, open your Amazon EC2 instance in the Amazon Web Console and head
to the Security Groups section. If you completed the steps in Part I
correctly, you should see that we have a Custom TCP Rule which allows
inbound access to port
27017 for all IP addresses (
0.0.0.0).

Great! Step 1 complete.
Now, we need to ensure that all IP addresses can run commands in
MongoDB itself. This allowance is helpful especially during development,
in which, many developers may need to access the database from multiple
machines. To do this, open up your PuTTY window again and
cd back into the main directory. From here, head into
Stack -> MongoDB.
cd
cd stack
ls
cd mongodb
ls

If you look into this directory, you’ll see a number of files and
folders associated with MongoDB. In our case, we will be opening the
mongodb.conf file and making a few edits using the vi editor.
sudo vi mongodb.conf
Once you’ve opened the file, you’ll see a list of config settings. Notice, for instance, where it specifies the port is
27017.
In our case, we’ll actually be changing the
bind_ip value to equal
0.0.0.0. This will allow all IP addresses access to our MongoDB instance. While still in the editor, type
i to enter insert mode. Change the value of the
bind_ip. Then type
:w to save and
:q to exit the editor.
This is how your config file would have looked before…

And after.

Once complete, navigate up one level back to the
stack folder. Then run the bash script in
ctlscript.sh to restart mongodb. This will ensure your changes to the MongoDB have taken effect.
cd ..
ls
sudo bash ctlscript.sh restart mongodb

At this point, our MongoDB database is ready for use by our MEAN application.
But, unfortunately, we have a few more steps to get things working for remote development and testing.
Necessary Workaround for MongoDB 3.0
To describe why this next step is necessary, open up a local terminal
and try to access your EC2 MongoDB database instance. Use the below
command as a guide.
mongo {EC2 DOMAIN}/admin -u {YOUR USERNAME} -p {YOUR PASSWORD}
At this point, what you’ll likely see is the aggravating response:
Error: 18... "auth failed". Try as you might in repeating your password or creating new users — this error won’t go away.

The reason for this error has less to do with your faulty memory and
more to do with the recent upgrade to MongoDB. With version 3.0, came a
new authentication mechanism
for MongoDB. In Mongo 2.0, a database could be accessed via a remote
shell or terminal so long as an admin username and password was
supplied. This was convenient for upstart developers trying to quickly
set things up. With the latest change, the authentication mechanism
requires a bit more work as many third-party tools (including Bitnami’s
default image) have yet to switch to the new drivers.
Fortunately, the MongoDB team has a relatively simple
workaround, in which we will revert our MongoDB setting to the old authentication mechanism.
To do this, first open up your PuTTY instance to EC2 and navigate to the
mongodb.conf file again.
cd stack
cd mongodb
ls
sudo vi mongodb.conf
Now, look for where it says:
auth = true. Temporarily, comment this value out, and uncomment the parameter that says
noauth = true. Save your changes (
:w) and exit the vi editor (
:q). Your config file should now look like the image below.

With this change to config settings, we could actually access MongoDB
remotely without even having to authenticate. But that’s clearly not a
solution we want. Instead, we are going to create a new administrator
that utilizes the old-form of MongoDB credentialing.
Now restart MongoDB again by running the restart script in
ctlscript.sh.
cd ..
ls
sudo bash ctlscript.sh restart mongodb
Finally, login to MongoDB and run the following to revert the authentication mechanism.
> use admin
> var schema = db.system.version.findOne({"_id": "authSchema"})
> schema.currentVersion = 3
> db.system.version.save(schema)
Your output should look like the below.

Now create a
new admin profile. This administrator will work
with the reverted authentication mechanism and work for remote
connections. To restrict access for this remote admin, I am going to
limit its access to the
dummyDB we created earlier.
> show dbs
> use dummyDB
> db.createUser({
user: "NEW USERNAME",
pwd: "NEW PASSWORD",
roles:[
{
"role" : "readWrite",
"db": "dummyDB"
}
]
})
Once created, go back again to the
mongodb.conf file, comment out
noauth=true, and uncomment
auth=true. (Essentially re-activate the authentication requirement). Your config file should now look like this:

Restart MongoDB again using the
ctlscript.sh and then try connecting to your Mongo instance via local terminal again.
mongo {EC2 DOMAIN}/dummyDB-u {New Username} -p {password}

Voila! Connection successful!
Incorporating the EC2 DB into our App
Okay. We have one final step before we can re-deploy our code. We
just need to incorporate the new MongoDB URI into our MEAN application.
Open up your forked
node-todo app from before.
Navigate to the
database.js file found in the
config folder.
Comment out the existing URL and replace it with the URL associated
with your EC2 instance of MongoDB. It should follow the format below:
'mongodb://{NEW USERNAME}:{NEW PASSWORD}@{EC2 URL}:{PORT}/dummyDB'
As a reference, here’s how my url looked:
'mongodb://todoAholic:scotchio@ec2-52-0-14-185.compute-1.amazonaws.com:27017/dummyDB'
Finally, run your code locally using
node server.js and navigate to
localhost:8080. If all went well the app should work as before. The big change is that you’re now using your EC2 instance of MongoDB. Huzzah!

Add a few to-do items in the web application. Then open up your PuTTY window, login to MongoDB, and query the
dummyDB database to confirm that the todo items match.
> use dummyDB
> show collections
> db.todos.find().pretty()
Do we have a match?

YES! Victory at last.
Pushing, Pulling, and Calling it a Day
We’ve been through a lot in these past two tutorials. All that’s left for us to do is to push our
node-todo code into Github and pull the updates onto our Amazon EC2 instance.
From your local dev environment commit and push your changes to Github.
git commit -m "Changed the DB URL to use EC2"
git push
Then from the
node-todo folder of your EC2 instance, run
sudo git pull

Finally, run forever to launch your MEAN application.
forever stopall
forever start server.js
And with that, it’s time to check out our finished work.
http://ec2-52-0-14-185.compute-1.amazonaws.com:8080/
Closing thoughts
After a long and hard slog we’ve
finally completed our EC2
deployment. In this two part tutorial we went through the process of
initializing an EC2 instance, setting up Node and MongoDB, configuring
security settings, and connecting our app to a running instance of
MongoDB located on our EC2 server.
As you can see, the process was arduous. But with the power of EC2
behind you, it becomes possible to create and deploy, low-cost MEAN
applications for the entire world to see. Good luck building something
great!
Comments
Post a Comment