Welcome back to BackSpace Academy. In this lab we're going to be creating a NodeJS 2
application using the serverless application model or SAM for short. 3
Now the AWS documentation can be quite a bit confusing on how to actually use SAM 4
so what I'm going to do is show you a process that I use and it's very simple 5
all I do is I have a github repository which has two files in it, one file will 6
be your SAM template and that will define where your code for your Lambda 7
functions is and also will define any other services that you require such 8
as an s3 bucket and it will also have the code which will be an index.js 9
file which will have your nodejs code for your Lambda application. So all 10
we need to do is bring that into the ec2 environment within Cloud9 and we just 11
need to create our package.JSON file which will reference any additional 12
packages that our application requires and from there we can just use SAM build 13
to prepare it for deployment and then use SAM deploy to deploy our application. 14
So let's get into it. Now all of the code is located in this Github repository 15
here so the the link for this is in the lab notes of course so the first thing 16
that you need to do is make sure that you star this repository that way you 17
can find it easy enough again if you need to and also so that other people 18
can find it as well so once we've done that we can have a look at our code so 19
we've got here our template.yml and that is going to define our Sam template and 20
so let's have a look at that so we've got a transform function or a transform 21
statement here and that is required so that tells us that word tells 22
cloudformation to use the service application model. Next we're creating 23
called create thumbnail and that is a lambda function now the properties for 24
this lambda function the code will be located in a folder called code and the 25
handler will be in an index.js file within code and that will have an 26
exports module called handler the runtime will be Nodejs the timout will be 27
60 seconds and the policy that we're going to use is the AWS managed Lambda 28
policy called AWS lambda execute and we're going to associate this with 29
an event so when something happens to an s3 bucket this event will be created and 30
that will invoke this Lambda function so the type of event is an s3 event and the 31
bucket is going to be referencing a bucket called sauce bucket which is down 32
here and the event is going to be s3 object created so whenever an object or 33
an image or whatever is put into this sauce bucket an event will be created 34
which will invoke this lambda function so let's have a look at this source 35
bucket so it it simply has type source or type AWS s3 bucket so what that will 36
do is it will automatically create an s3 bucket and it will name it with a unique 37
name so we also need to have a destination bucket so what this 38
application is going to be doing is that we are going to be uploading a file to a 39
source bucket and that will invoke this lambda function to process that image in 40
that source bucket and make a thumbnail of that image and put it into a 41
destination bucket so what we also need is a destination bucket and we would 42
like that destination bucket to have the same name as our source bucket but going 43
to have - resized on the end of it so what we've got here is at our 44
destination bucket it depends on our sauce bucket so we can't create this 45
destination bucket until this sauce bucket 46
exists and then we're going to give it a bucket name and that is going to be 47
joining the name of our source bucket with - resized on the end so what we use 48
is we use a cloudformation join function and the way that works is that 49
first off we define what is the character that we're going to put in 50
between these text strings so we're not going to have anything between them 51
we're just going to have the source bucket and then -resized so what 52
we're going to do there is just have two inverted commas with a dash in there and 53
we're going to define then what the two text strings are and so it's going 54
to be referencing our source bucket name and then we're going to have - resized 55
so the bucket name will be the join of a resource bucket name with - resized on 56
the end so we're going to have two buckets and when we drop an image into 57
this source bucket that will create an event which will invoke our lambda 58
function so let's go back to the cloud9 console and get this happening okay 59
starting off here in the cloud9 IDE we're going to be using the ec2 60
environment of cloud 9 to build our application so what the first thing we 61
need to do is we need to clone our repository so git clone and then the URL 62
of our repository again this is all in the lab notes make sure you download 63
those so that's done that for us and if we look at our directory tree we can see 64
that we've got our template demo and I've got a code in there so let's take a 65
look at our template demo and what we can see here is that it's referencing 66
our runtime so we need to make sure that the runtime that we're referencing here 67
for Lambda to run is going to be the same as a runtime that we're going to be 68
using to build this so let's just check what our node version is on our ec2 69
environment here in cloud 9 70
so there we can see we're running version 10 in cloud 9 71
whereas our template is referencing version 12 of node and that's pretty 72
common for some reason I don't know why cloud 9 seem to be a bit slow with 73
updating its version so we just go into here and change that to version 10 so 74
that wiill be nodejs10.x and we just do ctrl s to make sure that we save that 75
and we just get out of that now and just close that might as well just leave that 76
open for now and let's have a look at our code here so we've got our index.js 77
and we'll open that up and have a look at that so we can see here it's 78
going to require the AWS software development kit that is not a problem 79
for us land that includes it and you tools is also included with the Lambda 80
service when it is invoked but sharp is not so we need to install sharp on this 81
environment and that we need to do that with a package.json that references that 82
sharp that sharp package so what we're going to do is is we're going to change 83
into our code directory and again just copying from the lab notes it says the 84
easiest way to do it and what we need to do now is that we need to create a 85
package JSON file so NPM in it and we're just going to call the code package code 86
that's fine leave everything as it is everything looks and our entry point is 87
going to be indexed which is which we've got there and ok yes ok so that has 88
created a package JSON so we open it up there it's pretty well got no 89
dependencies there whatsoever so what we need to do now is that we need to do or 90
we need to install sharp and that will put that reference that in our package 91
JSON as well as installing sharp so we do NPM installed and sharp 92
so now if we open up our package.json 93
and then we can see it's put the dependency of Sharp in there so we 94
don't need any of these new modules now because Sam bill doesn't need that will 95
create all those so we can keep this quite small now so all I need to do is 96
just delete that so it's going to select it press Delete and that has gone so 97
we've got everything we need now we've got our template which is going to 98
define our Sam and how Sam is going to package and deploy our application we've 99
got our index which index J s and we've also got our package JSON which is going 100
to list all of the packages that our application requires so all with all 101
that we need to do now is to go back up to the main folder there which has got 102
our template.yml file in there and so now we can just do a Sam build and 103
that will build this application for you and it will prepare everything force and deploy 104
so we do Sam build so that has successfully built our application so 105
with three files only which is our template.YML our package JSON and our 106
index.js is all that we needed to build our application it's a very simple 107
process to follow this so once we've done that all we can do now all you need 108
to do now is just SAM deploy. So Sam deploy - - guided. Okay and that 109
will guide us through the deployment process so we'll give this would just 110
leave it with the stack name of Sam app but easy enough to remember and the 111
region is us east one confirmed changes to port before deploying yes we will and 112
allows the CLI or the Sam CLI to create a role yes and save arguments 113
to Sam configure it's fine so now it will be preparing that 114
changeset for us and asking us whether we want to deploy that ok so what it's 115
doing here is it is going to be creating some Lambda permissions and then it's 116
going to use those permissions to create an IAM role for lambda and then it's 117
going to be creating that Lambda function it's also going to be creating 118
a destination bucket and a source bucket 119
ok so after a few minutes all of these resources have been created for us quite 120
successfully so what we can do now is that we can go into the s3 management 121
console and we should see those two buckets that were created so if you look 122
at our template ml and we can see that we did create a source and destination 123
buckets and the destination bucket will be the same name as a source bucket but 124
with -resized on the end of it so let's have a look at that we'll just 125
refresh 126
so there we can see our Sam app source bucket and a bit of a hash string there 127
- resized and the or that's the source bucket there and then - resized is our 128
destination bucket so if we go into this will open both of them up so we go into 129
our source bucket and what I'm going to do is just upload an image 130
and just to get that through accept all the defaults if that's fine okay so 131
that's uploaded that that object that JPEG file so what's going to happen now 132
is that that world trigger and s3 event that s3 event will invoke that Lambda 133
function which will then grab this data JPEG file it will create a thumbnail 134
image of that and it will store it into our destination source or a destination 135
bucket so let's go to that destination bucket now and we're just going to 136
refresh that and there we can see so resize data JPEGs so let's have a look 137
at that original one where's 150 K and the next one is 9.8 K 138
so it's created a thumbnail of that not a problem so that has worked what I want 139
to do now is actually have a look at this code and see how it everything 140
actually worked so let's open up our index page is and have a look at it so 141
first of all we have our exports handler so that is going to be our index.js 142
well when we reference that in our template.yml it's going to be our 143
index.js and then what that module that we're exporting and here are going to be 144
calling it handler so the first thing we're going to do is that we're going to 145
get the source bucket and that is going to become is 146
going to come from the event that triggered this s3 bucket name so how do 147
we know that so why we do that as we go to the two the s3 documentation so here 148
we are in the s3 developer guide so we just go down to notifications and then 149
we can see event message structure so let's just scroll down and see what it 150
looks like so it's going to be an array called records and having a few objects 151
in there so what we've got here is s3 bucket and name so go back to our cloud 152
9 we can see that we've got s3 bucket and name and we also need to know what 153
the source keys so what the actual name of that image file 154
all that we uploaded is and so again we'll go back to the event structure and 155
we can see here we've got s3 object and key so if we go back to our code we can 156
see there we've got its three object and key so now we we know what the source 157
bucket is we know what the file name is and from there we can create our 158
destination bucket which will be the same as the source bucket or we can 159
reference our destination bucket it's already been created and that will have 160
the name sort of their source bucket with - resized on the end of it and our 161
destination key and that's what we're going to use there which is going to be 162
based upon our source key as well so then what we need to do is to infer our 163
image type and make sure that is either a JPEG or a PNG type file so once 164
everything is fine we've got a jpg or PNG file in there we can download that 165
image so we need to get the parameters which will be the bucket source bucket 166
and the source key for that image and so then we're going to download that using 167
the get objects command from the AWS software development kit and so once 168
we've got that image we can then apply sharp to that image so sharp will get 169
the original image which which we've got here and it's going to resize it to a 170
width of 200 and it's going to put it into a buffer so that you will have 171
temporary storage of that file for us if there's an error it will lock 172
console.log out that error so once we've got the original image and we've got it 173
stored in a buffer we can now get it back use it or we can now upload it to 174
the destination file or the destination folder with that thumbnail image so we 175
have our destination parameters which will be our destination bucket and our 176
destination key and what is going to be going in there will be in our buffer so 177
the buffer will contain the thumbnail image that we created using 178
which will be 200 pixels wide and the content type will be image so once we've 179
created those parameters we can pass those parameters to a put object command 180
and once that's successfully done that will be fine and our object our 181
thumbnail image of our original image will be uploaded to that bucket so quite 182
straightforward we're simply just getting that image from the event s3 183
bucket name and the name of the image from s3 object key and then we're using 184
sharp to resize it to 200 and putting it into a buffer and then we're just 185
getting put objects to put it into our destination bucket into that destination 186
key from the buffer so let's now jump into lambda and have a look at how it 187
all worked so just going to the lambda management console and this time we're 188
going to look at the application we actually created a application that 189
consisted of multiple parts not just a lambda function so there's our 190
application Sam - app if we click on that 191
and we can see that it's created or it's made up of a lambda function and - s3 192
buckets and so there will be a link to the s3 buckets and here is a link to our 193
Lambda function so there's our lambda function and what we can do is we can go 194
to monitoring and view the logs in cloud watch and see what was produced through 195
the console dot log so scroll down there's our log stream so let's have a 196
look here so we've got the first one here so it received again at that event 197
record and within that event record we had s3 bucket and bucket name and we 198
also had the key which is data dot JPEG so that file that I uploaded and then 199
what happened next was it successfully resized 200
Sam app sauce bucket data JPEG and uploaded it to Sam app source bucket 201
resize JPEG so that's pretty cool everything worked fine so I think I've 202
shown you everything that you need to really know about this same process and 203
I hope you in I hope you got a lot out of it and I I hope you enjoyed it and I 204
look forward to seeing you in the next one but before we do that we'll just 205
clean this up so we need to first off empty our buckets so we'll get this 206
bucket and empty it 207
we'll go to the next bucket or resize bucket well empty that as well 208
so now that our buckets are empty we can just go into cloud formation and delete 209
our Sam apps we're just going to refresh this make sure it's all okay yep and 210
delete our Sam app make sure you don't delete these other two just delete the 211
Sam app and delete that stack so after a certain amount of time that will delete 212
all of those Lambda resources those s3 resources and that that that app if you 213
want we can go into here also in to delete our code as well so just delete 214
that and there we go that's done so I look forward to seeing you in the next 215
one