WEBVTT

00:00.230 --> 00:04.670
Let's look at how we can run our microservices on AWS.

00:04.700 --> 00:11.330
We're going to use Amazon ECS to run our Kubernetes cluster as well as exposing an external load balancer

00:11.330 --> 00:14.690
so we can access our Nestjs app.

00:14.810 --> 00:20.510
We're also going to set up a build pipeline so that our Docker images will be rebuilt and pushed to

00:20.510 --> 00:26.110
an AWS image repository whenever there is a new commit to our GitHub repository.

00:26.120 --> 00:33.290
So to get started, head to aws.amazon.com and you can click on log back in from here.

00:33.290 --> 00:38.690
You can sign in if you have an account or if you'd like to create a new account, follow through with

00:38.690 --> 00:39.560
these steps.

00:39.560 --> 00:42.140
So signing up for AWS will be free.

00:42.140 --> 00:49.070
However, actually running the ECS cluster will cost up to $0.10 per hour to run the cluster.

00:49.070 --> 00:52.400
And we're also going to be charged for the underlying compute that we use.

00:52.400 --> 00:57.680
So the instances that we're using, we're going to use two micros in this tutorial, which is a free

00:57.680 --> 00:58.580
instance type.

00:58.580 --> 01:02.220
So we can set this cluster up really cheaply and explore with it.

01:02.220 --> 01:05.670
However, you will need to associate billing details with your account.

01:05.730 --> 01:06.090
All right.

01:06.090 --> 01:11.130
So after you've finished signing up, you should find that you're in this AWS management console.

01:11.130 --> 01:17.010
We're going to start off by setting up an image repository so we have a place where we can push up our

01:17.010 --> 01:23.730
built Docker images to let's go ahead and search for ECR, which stands for Elastic Container Registry,

01:23.730 --> 01:27.540
which as we can see, is a fully managed Docker container registry.

01:31.670 --> 01:36.350
Now that we're at ECR, let's click Get Started to create our repositories.

01:36.350 --> 01:41.240
So we're going to go ahead and create private repositories so that only we and our Kubernetes cluster

01:41.240 --> 01:43.640
can actually pull these images.

01:43.640 --> 01:47.390
We're going to create a repository for each one of our microservices.

01:47.390 --> 01:54.200
So let's go ahead and start off with the reservations Microservice and click Create Repository.

01:55.570 --> 01:59.700
Let's go ahead and repeat the same process for our three other microservices.

01:59.710 --> 02:01.660
The auth microservice.

02:03.760 --> 02:05.590
Notifications.

02:10.190 --> 02:13.780
And lastly, I'll create a payments microservice.

02:13.790 --> 02:17.030
So now we have repositories to push our Docker images to.

02:17.030 --> 02:22.370
Let's go ahead and give this a try locally on the command line to make sure we can correctly authenticate

02:22.370 --> 02:24.040
and push our images up.

02:24.050 --> 02:30.320
All right, so we're going to need the AWS CLI installed on our system to easily interact with the AWS

02:30.350 --> 02:32.120
console from the command line.

02:32.120 --> 02:39.890
So if you don't already have the CLI, go to Aws.amazon.com, slash CLI and then we can click on getting

02:39.890 --> 02:42.650
started here.

02:42.650 --> 02:47.090
We can see how to install the CLI based on your operating system.

02:47.090 --> 02:54.290
So click on your operating system and follow these instructions to easily install the AWS CLI.

02:54.650 --> 03:02.840
So after you've installed the AWS CLI, you should be able to run AWS configure to set up new credentials

03:02.840 --> 03:04.820
to get access to these credentials.

03:04.820 --> 03:11.910
Go back to the UI console and click on your username in the top right corner and then click security

03:11.910 --> 03:13.440
credentials from here.

03:13.440 --> 03:19.980
We'll scroll down until we find access keys and we'll click Create Access Key.

03:20.310 --> 03:26.220
We'll go ahead and continue using a root access key in case you'd like to create a user with finer grained

03:26.220 --> 03:32.970
control over the permissions they have, you can create a new user in IAM, sign in to that user and

03:32.970 --> 03:35.970
then go back to create access key just for that user.

03:35.970 --> 03:42.000
In our case, we want our root user to be able to do anything with this access key because we are using

03:42.000 --> 03:43.080
it ourselves.

03:43.080 --> 03:49.830
So we'll go ahead and grab the access key and paste this in to the CLI.

03:50.790 --> 03:55.320
Then we'll copy the secret access key and paste that in as well.

03:55.350 --> 03:59.490
You can feel free to select whatever default region you'd like.

03:59.490 --> 04:05.580
I'm going to use us East one and we've gone ahead and correctly configured AWS CLI.

04:06.060 --> 04:13.590
Now let's go back to ECR and we can click on any one of these repositories and in the top right we can

04:13.590 --> 04:19.800
click on View Push commands to get a list of commands to actually build and push our image up.

04:20.160 --> 04:27.720
So let's copy this first command, which is going to authenticate our CLI with ECR by calling AWS CLI

04:27.870 --> 04:30.180
and then piping that to Docker login.

04:30.180 --> 04:35.670
So of course make sure you have Docker running on your system before we execute this and then I'll paste

04:35.670 --> 04:38.880
this command in to go ahead and log in.

04:39.420 --> 04:47.490
Now after we've logged in, we'll go ahead and CD into our apps folder and then CD into reservations.

04:47.490 --> 04:52.260
We can copy the next command to build the Docker image and paste it in.

04:52.290 --> 04:54.180
Now we'll make a modification.

04:54.180 --> 04:59.310
We're going to specify that the path to the Docker file is in our current directory, but we want this

04:59.310 --> 05:04.080
to be run from the root context, from the root of our project.

05:04.380 --> 05:04.680
All right.

05:04.680 --> 05:11.010
So once our image has finished building, we'll go ahead and then get this command to tag our image

05:11.010 --> 05:17.160
based off of our repository name so we can copy and paste this command directly.

05:17.850 --> 05:24.750
And finally, we'll run this last command, which will just push the Docker image up to our AWS ECR

05:24.750 --> 05:25.740
repository.

05:25.770 --> 05:28.380
You can see that the push is progressing.

05:30.320 --> 05:37.790
So once the image has fully pushed up, we can refresh the browser and we should see our reservations.

05:37.790 --> 05:40.400
Image has pushed up with the tag of latest.

05:40.400 --> 05:44.210
So now we have the ability to push images up to ECR.

05:44.240 --> 05:50.450
Let's see how we can set up a CI CD pipeline to automate this process for our remaining microservices

05:50.450 --> 05:54.530
and ensure we always have the latest code available in these Docker images.

05:54.830 --> 06:00.530
So we're going to define a list of steps how to automatically build our Docker images and then push

06:00.530 --> 06:01.970
them up to ECR.

06:02.000 --> 06:09.530
In order to do this, we need to create a new file called Build Spec dot YAML and make sure this file

06:09.530 --> 06:11.510
is in the root of our project.

06:11.510 --> 06:14.000
Firstly, we'll go ahead and define the version we're using.

06:14.000 --> 06:19.610
In this case it'll be 0.2 and then we can define some phases for our build.

06:19.640 --> 06:26.540
The first one will be a pre build phase where we will execute a command section and in here we'll have

06:26.540 --> 06:27.620
a list of commands.

06:27.620 --> 06:31.290
So the first command we'll need is to actually log in to ECR.

06:31.320 --> 06:38.130
We can take this command from our AWS ECR console where we click on View Push commands and copy this

06:38.130 --> 06:43.380
first command where we get the log in key and pass it to Docker login.

06:43.380 --> 06:47.010
So go ahead and copy this command and paste it in.

06:47.010 --> 06:50.310
So this is all we need to do inside of the pre build phase.

06:50.340 --> 06:56.310
Next we'll go into the actual build phase itself where we'll have another list of commands and now we're

06:56.310 --> 07:02.670
actually going to execute the Docker commands to build and tag our images so we can copy this first

07:02.670 --> 07:05.550
build command from ECR and paste it.

07:05.550 --> 07:11.730
We're going to specify the path to the Docker file will be in dot slash apps, slash reservations,

07:11.730 --> 07:17.760
slash Docker file and the build context or where we want to build the Docker file from will be the current

07:17.760 --> 07:18.840
root directory.

07:18.840 --> 07:24.950
So next we can go ahead and copy the command to tag the reservations image and paste it in.

07:24.960 --> 07:31.590
Notice we're using the latest image tag, so let's go ahead and copy these two commands and then we

07:31.590 --> 07:35.700
can go ahead and just paste them in a few more times.

07:35.700 --> 07:39.240
And we're only going to have to change the service that we're building.

07:39.240 --> 07:46.080
So we're going to build the auth service and tag the auth service at TAG latest.

07:46.110 --> 07:51.960
We'll go ahead and do the same thing now for the payment service, make sure we go into slash payments

07:51.960 --> 07:56.400
and make sure we tag the payments image correctly.

07:56.430 --> 08:01.260
Finally, we will tag the notifications image.

08:06.910 --> 08:10.840
So now that we've built and tagged our images, we're ready to actually push them up.

08:10.840 --> 08:13.930
And we'll do this in the final stage of the build.

08:13.960 --> 08:21.730
This will be the post build stage where we'll specify a new set of commands to actually push the Docker

08:21.730 --> 08:23.530
images to our repository.

08:23.530 --> 08:30.160
So we'll take the last command of Docker push and then we'll paste this in a few more times, just swapping

08:30.160 --> 08:33.850
out the name of the image to auth.

08:34.880 --> 08:35.990
Payments.

08:36.920 --> 08:38.960
And notifications.

08:39.290 --> 08:45.890
So now we have a completed build spec that will give Codebuild the set of instructions it needs to properly

08:45.890 --> 08:47.750
build, tag and push our images.

08:47.750 --> 08:52.940
So finally, don't forget to actually commit your change so that it will be available when code builds,

08:52.940 --> 08:54.890
scans our GitHub repository.

08:54.890 --> 08:59.150
So I'll commit a message saying add build spec.

09:00.290 --> 09:02.540
And push this to my repository.

09:03.080 --> 09:09.380
So we're ready to utilize code build in that build spec to actually set up our automated builds.

09:09.410 --> 09:15.110
We're going to use code pipeline to accomplish this, which will allow us to easily detect new commits

09:15.110 --> 09:17.480
and build them with our build spec.

09:17.480 --> 09:21.710
So look up code pipeline in the search bar and click on Code pipeline.

09:21.710 --> 09:23.930
We want to create a new pipeline.

09:23.930 --> 09:27.080
So click create pipeline and call it whatever you'd like.

09:27.080 --> 09:28.460
I'll call this sleeper.

09:28.490 --> 09:30.680
Next, we can select a service role.

09:30.680 --> 09:35.960
So click on Create new Service Role and use the default name provided and click next.

09:36.410 --> 09:40.460
Next, we're going to go ahead and specify the source provider for our code.

09:40.460 --> 09:46.880
So in our case, this is going to be GitHub version two, you can select which source provider you use.

09:46.910 --> 09:48.500
However, we're going to use GitHub.

09:48.500 --> 09:53.750
So in order to set up our GitHub provider, we need to create a new connection.

09:53.750 --> 09:58.550
So go ahead and click connect to GitHub to set up a new GitHub connection.

09:58.550 --> 10:00.420
You can call this whatever you would like.

10:00.420 --> 10:04.800
I will call this the name of our app Sleeper and click connect to GitHub.

10:06.130 --> 10:08.740
Next we need to set up the GitHub app.

10:08.740 --> 10:14.590
So click on install a new app to be redirected to GitHub and supply your credentials.

10:14.590 --> 10:19.450
You should be brought to this page where you install an AWS connector for GitHub.

10:19.450 --> 10:23.200
Go ahead and select the repository for your application.

10:23.200 --> 10:29.410
In this case it will be my sleeper repository and go ahead and click install.

10:30.010 --> 10:36.610
After the installation you should have a GitHub app prefilled as form and then we can click on Connect.

10:36.970 --> 10:43.420
We can see that our GitHub connection is ready to use and we can select the repository from this dropdown.

10:44.200 --> 10:49.120
We can also select the name of the branch that we'd like to build from and watch commits.

10:49.120 --> 10:53.890
In this case I'm going to use the main branch and we will keep this box checked that will start a new

10:53.890 --> 10:56.200
pipeline and source code changes.

10:56.200 --> 11:02.380
Finally, for output artifact format, click on code pipeline default and then click next.

11:02.410 --> 11:08.320
Now we have to set up our build stage and we're going to select AWS Codebuild as our provider.

11:08.320 --> 11:13.180
And then we need to select a project in Codebuild to use for this pipeline.

11:13.180 --> 11:18.430
In our case, we don't have one yet, so we'll click on the Create Project button and get redirected

11:18.430 --> 11:19.990
to code build.

11:19.990 --> 11:25.300
So now we're setting up a new Codebuild project and we can call this sleeper as well.

11:25.300 --> 11:28.990
Then scroll down until you find the environment image.

11:28.990 --> 11:35.980
We will use an Amazon Linux two for our code build operating system and for the runtimes we will select

11:35.980 --> 11:44.030
standard and the image we will use AWS code build 86 by 64 standard 4.0.

11:44.110 --> 11:50.560
Then click on the privilege box so that we can build Docker images and create a new service role for

11:50.560 --> 11:51.580
this code build.

11:51.580 --> 11:58.030
Then if we scroll down, we can see the build spec section where we specify the Buildspec.yml.

11:58.060 --> 12:04.840
However, we can actually leave this blank because by default it will look in the root for a buildspec.yml

12:04.840 --> 12:10.640
which we have already provided so we can continue down to the bottom and click continue to code pipeline.

12:10.640 --> 12:17.120
You can see we have successfully created the project and code build and now we can click on next back

12:17.120 --> 12:18.170
in Code Pipeline.

12:18.170 --> 12:24.050
Then for the deploy stage, we are going to click on Skip, deploy stage and then click Skip.

12:24.730 --> 12:30.100
We can see all of these settings we have configured and we will click on Create Pipeline.

12:30.730 --> 12:36.340
Now we can see we are brought to the dashboard where we can see our source has successfully executed

12:36.340 --> 12:38.890
and our build stage is currently in progress.

12:38.920 --> 12:45.490
We can click on the details link and then we're brought to the logs for the current build.

12:46.110 --> 12:47.250
In code build.

12:47.250 --> 12:51.180
You can see on the left side here we are under the code build section.

12:51.300 --> 12:58.270
This is our in-progress build and we can click on tail logs to follow along with this build.

12:58.290 --> 13:04.140
It's currently in the pre build section where it's logging in to Docker and you can see an error has

13:04.140 --> 13:11.980
been thrown because the assumed role is not authorized to perform get authorization token on resource.

13:12.000 --> 13:18.150
This is because our code build service role we've created has not been given permissions to actually

13:18.150 --> 13:19.710
interact with ECR.

13:19.740 --> 13:28.020
Let's go ahead and fix this by going to IAM service console and clicking on IAM and we can see our code

13:28.020 --> 13:35.460
build sleeper service role, click on this role and then click on add permissions so we can add some

13:35.460 --> 13:37.650
new policies to this user.

13:37.650 --> 13:41.910
And then we're going to go ahead and filter out for ECR.

13:41.940 --> 13:49.780
We can see a prebuilt policy here called EC2 instance Profile for Image Builder, ECR container builds.

13:49.780 --> 13:56.530
And if we open this up, we can see a list of permissions that allow this role to actually push images

13:56.530 --> 14:01.300
up to ECR, including that get authorization token permission.

14:01.300 --> 14:07.240
So let's go ahead and click on this permission policy and then click on Add Permissions.

14:07.270 --> 14:14.830
Now you can see this Codebuild role has the ECR permissions it needs, and we can go back to codepipeline

14:14.830 --> 14:17.260
to re trigger a new release.

14:17.260 --> 14:23.470
To trigger this release, we'll click on our pipeline and then click on Release Change and then click

14:23.470 --> 14:24.550
on release.

14:24.580 --> 14:31.450
You can see a new build is in progress and we can click details and tail logs to follow along with this

14:31.450 --> 14:32.200
new build.

14:32.320 --> 14:39.190
After the build has finished completing and all of our images are pushed up to ECR, we can close this

14:39.190 --> 14:42.100
and see that the build was successful.

14:42.490 --> 14:49.390
And if we go back to Codepipeline now into our sleeper pipeline, we can see that the source and build

14:49.390 --> 14:50.740
have both succeeded.

14:50.770 --> 14:54.280
More importantly, if we go back to ECR now.

14:56.620 --> 15:00.850
All of our services have a latest image pushed up to them.

15:00.880 --> 15:03.910
This latest tag has been pushed up from Codebuild.

15:03.910 --> 15:11.350
So now we have our images automatically build any time we make a new git commit and push that up to

15:11.350 --> 15:13.570
our repository, which is great.

15:13.900 --> 15:21.160
Next, let's look at how we can run our Kubernetes deployment on Amazon, ECS and provision a load balancer

15:21.160 --> 15:23.500
so we can access this cluster externally.
