Zero to Production Node.js on Amazon Web Services Production Environment Demo Part 3
This course has been updated! We now recommend you take the AWS for Front-End Engineers (ft. S3, Cloudfront & Route 53) course.
Transcript from the "Production Environment Demo Part 3" Lesson
>> Kevin Whinnery: There's a lot of different configuration options here, which I'll get into in a little bit. But now that we have the security group created, I'm gonna go ahead and create an Amazon RDS instance to associate with this environment. So it is possible to create an RDS instance within the Elastic Beanstalk administrative interface.
[00:00:27] But they recommend against doing that for a production configuration because environments are not necessarily durable. They do get created and deleted with more frequency. So the typical way that you are instructed to set this up is to create an RDS instance independently and then add it to the security group associated with your Elastic Beanstalk EC2 instances, so they can talk to each other.
[00:00:56] So that's what we're gonna do right now. So we'll scroll down, I'm on the console home page, and go to RDS.
>> Kevin Whinnery: And we'll go down to Instances, and we are going to launch a DB instance. And in this case, we are going to choose Postgres. And to stay in the free tier, we'll use this dev/test version of Postgres.
[00:01:27] And then the other handy option here is only show options that are eligible for the free tier, so for just messing around, it's good to,
>> Kevin Whinnery: Check that out. And we can leave the defaults here for the most part. So the database instance identifier we will call to dos or to do NBC, it doesn't really matter.
[00:02:03] And then we're gonna configure a username and password for our database. Now in this case, because our database isn't open to the world, these aren't necessarily super secret squirrel values. So I'm gonna choose aws user and aws password for these values.
>> Kevin Whinnery: And now I'm going to select the security group to add this instance to.
[00:02:44] I can leave those default settings, but I need to be able to choose the security group associated with my EB instance. So let's see, EWSEB security group. I forget what it actually was. Let me go to my output here.
>> Kevin Whinnery: Might have to go refresh my memory on which one that was.
>> Kevin Whinnery: And as we can see, our environment is degraded right now because it's underconfigured, and we still need to do a few things. I'm gonna go in here, go into my instance configuration, and see that security group is something that looks like that, XTUIAQ.
>> Kevin Whinnery: And we don't want the load balancer security group, we want the Elastic Beanstalk security group because it's those EC2 instances that need to actually talk to the database.
[00:03:51] And now these values matter, if you remember the database name that we have configured by default in our configuration, I believe it's just called todos. So that's we're gonna call it in our actual application as well. We can leave the default port, and a lot of these other options we can tweak a little bit.
[00:04:18] But right now, we can launch our instance, and it is gonna take a few minutes, that is not a lie. So that instance is being spun up, it's gonna be added to the security group that our Elastic Beanstalk application can access. So while that's happening, let's head back into the console for Elastic Beanstalk and do some configuration that we needed to take care of anyway.
[00:04:47] So at the software level, there's a couple things we need to do. So this software configuration refers to the actual Linux operating environment that our application is executing in. And there are some other properties that we can tweak in here that will be useful. So for a Node.js instance, you have the option of using either engine X or Apache as a proxy server for your Node JASS application, or you can use you know proxy server at all.
[00:05:19] But probably, you do you want to have that, and then you can specify which Node version you'd like to run on your instances. And the most recent version of Node that you can elect for your instance right now is 622. There is a listing of this in the documentation that you can refer to.
[00:05:40] So we'll update that to the latest Node version that we can. We'll leave this blank because we have an NPM start script, which is going to specify the command, which actually launches our web application. And now when we scroll down a little bit, there are a couple of pieces that we do wanna configure.
[00:06:01] So one of the things we wanna make sure we do is have our static assets served by engine X rather than Node cuz engine X is going to do a much faster and better job of serving those up for us. So we're going to map the static path, so any incoming HTTP requests that go to /static will be mapped to a virtual directory within our application.
[00:06:29] In this case, that's going to be the public directory, which is generated by our Grunt tasks. So, we're gonna go ahead and add that. And we also need a couple environment variables, so we are actually gonna be populating our RDS connection string here, but we don't have that quite yet.
[00:06:53] So what we'll do for now is configure a few other bits we need, number one is we need to create a environment variable indicating that our Node environment is production. We also need to indicate that for NPM, NPM should only install the direct dependencies of our project, not the dev dependencies.
[00:07:17] They don't need to install all the Grunt crap that we need for local development. They just need the production dependencies. So, I'm gonna specify NPM_CONFIG_PRODUCTION equals true.
>> Kevin Whinnery: And then just as a placeholder, I'm gonna put in RDS_CONNECTION_URL, and that's going to be the actual database connection string for the Postgres database that we just kicked off the creation of a little while ago.
[00:07:58] So let's go over here and view our database instances and see how we're doing. So, it looks like our instance is not quite created yet, so we don't have an endpoint for it as yet. So, once it's actually created, we'll have an endpoint that our Elastic Beanstalk application can actually address in this application.
[00:08:25] So, hasn't been created yet, so we'll check back here in a little bit. But for now, we'll apply those configuration changes. And whenever we change the configuration like this, the environment is gonna start an update. So if you only have one instance, Elastic Beanstalk will spin up another instance and begin the update.
[00:08:55] And then once the update is complete, it will start accepting all the traffic, and then other instances that need to be updated will be updated after that. Yeah, so this is going down. We'll check in again on our RDS instance.
>> Kevin Whinnery: Still creating.
>> Kevin Whinnery: All right, so once we have the RDS URL that we can add to our configuration, we are gonna be mostly ready to actually deploy.
[00:09:35] So to get ready for that, we're going to run the Grunt collect_static command.
>> Kevin Whinnery: What's going on?
>> Kevin Whinnery: Unable to find local grunt, yeah, we need to do npm install.
>> Kevin Whinnery: All right, so these steps that are actually preparing the application, in our case, happen on a continuous integration server.
[00:10:06] So when we push a commit to master, RCI server is going to create all of our static assets and do whatever command line functions are necessary to get our application ready to deploy. And then we will actually zip up a deployment artifact that we will send to Elastic Beanstalk from our CI server.
[00:10:35] We'll send that to S3, and then we'll kick off a deploy of that artifact that we created. In our case, we're gonna be doing the creation of the zip file right here on my laptop. But typically, what you would do is set up a continuous integration server that would actually execute all of these tasks for you.
[00:10:54] So we're doing npm install getting all of this ready, so we can execute our Grunt task to create our static assets and the public directory where all of those will be held.
>> Kevin Whinnery: So while that's happening, we can check back in on RDS land.
>> Kevin Whinnery: So it's backing up, which means it's pretty close, that's good.
>> Kevin Whinnery: All right, and while that's happening, there is one last piece of configuration that we need to do. We're gonna go into our EC2 configuration.
>> Kevin Whinnery: Let's see where is this,
>> Kevin Whinnery: Clusters, task definitions, repositories. Wait, that's ECS, not EC2. That is for Docker containers, I'm not interested in Docker containers right now.
>> Kevin Whinnery: All right, so we're gonna go into our security group configuration for our EC2 instances and look for some security group. So we have two security groups that were created for our todo NBC application. One was created for our Elastic load balancer configuration, and one was created for our EC2 instances.
[00:12:36] So I'm going to take a look at this one.
>> Kevin Whinnery: And yup, I think that's the security group we're looking for. Now, I need to go over here to the inbound tab, I see a lot of heads in hands here. I know, I feel your pain, but the initial setup is definitely where most of the pain is.
[00:13:07] So what we're gonna do is edit inbound rules, and we already have a rule that's gonna allow HTTP requests on port 80 to be accepted for the security group. We're gonna add a rule, it's going to be for Postgratis SQL. And we are going to put in the security group again for our EB instance.
[00:13:33] So that's gonna be this one, this AWS EB security group blabadee bloop. And we'll hit Save.
>> Kevin Whinnery: This is being recorded. Don't worry, you can go back and check it out. All right, so now, let's see if we have our RDS instance ready to go.
>> Kevin Whinnery: Awesome, it looks like it is available.
>> Kevin Whinnery: So now if we go to the configuration details, we can see we actually have an endpoint for it, which is great. That means we can configure an environment variable in our EC2 instances, which contain the connection string for the database.