Resize Images with Node.js and AWS Lambda (and S3)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's going on guys welcome back to another video today we're going to create a Lambda function that will automatically resize images when they get uploaded to S3 to demonstrate I have two buckets one that stores the original image and one that stores the resize thumbnails so I'll upload an image to the image bucket I'll select this golf course let's verify that the image uploaded successfully and there it is now we should see a resize thumbnail that was generated automatically by our Lambda and there it is the web did this all behind the scenes without us having to directly invoke it so if you guys want to learn how to do that stick around and let's get started [Music] the way that this will work is a user is going to upload a photo to our S3 bucket once the photo successfully uploads the bucket will notify our Lambda saying that a new image was uploaded and it's going to pass along the key the webda will then take this key fetch the original image from the bucket then resize it and do any extra processing that it has to and then store it in a new bucket this new bucket will only store the resized versions of the original images this is all possible thanks to Lambda triggers a Lambda trigger is just something that triggers your Lambda when a specific event occurs in our case our trigger will be an S3 bucket and it will invoke our Lambda when a new image is uploaded so we never have to call the Lambda ourselves because the trigger will automatically invoke it for us let's start by creating our S3 buckets we'll go over to S3 let's hit create bucket and we're going to create our images bucket first that will store the original we're going to call it demo user images bucket then we could leave all these settings as default and create the bucket now let's create the bucket that will store our thumbnails and we'll call it demo user thumbnails bucket and then just hit create at the bottom now let's upload our first image to our images bucket let's view it just to make sure it uploaded correctly and there we go so this will be the base image that we are going to resize now let's create our Lambda so I'm going to go to the Lambda console then click create function we'll give it a name of demo image resizer Lambda we'll set the runtime to node 18. now we need to add an execution Rule and this is basically just a role that will give the Lambda permission to access our buckets because by default the Lambda doesn't have permission to do anything unless we give it a roll instead of using one of these options let's go ahead and create our own custom role so let's open IAM we'll select Lambda as our service for our role we have to attach a policy to it and a policy just defines a set of specific permissions let's go ahead and create a policy then click on the Json Tab and if you look at the code that I put in the description you'll see that there's a policy.json and you're just going to copy that and paste it into our editor here and this just to finds some permissions for our Lambda like giving it access to send logs to cloudwatch we're also giving it read access to a bucket that we Define and then we give it right access to a bucket let's replace these placeholder values with our actual bucket names our first bucket was demo user images so I'm just going to copy that over and this forward slash star just means every object within the bucket if we wanted to limit it to a certain prefix then we could add that in here let's grab our other bucket now that we've changed those values we should be good to go we'll give the policy a name of image buckets policy because it gives access to our image buckets then let's hit create policy now that we made the policy let's go ahead and attach it to our role let's refresh our list and then look up image buckets policy there it is let's go ahead and select that we don't need any tags and we'll give the role a name of image resizer Lambda role then let's click create role once that's done we could go ahead and attach that rule to our Lambda so we could hit use existing rule and we'll refresh this to make sure it catches it and there it is then let's hit create function here's the Lambda dashboard and if you scroll down to the bottom you can see the source code that runs when the web is invoked right now it's just this default handware that they gave us and we need to replace this with our own Lambda code I have the finished handware Linked In the description below so you guys can open up that repo and see what the Handler does I'm going to run through it real quick and if you guys wanted to tweak the code and zip it up before deploying it to your Lambda just note that if you're on Mac when you install the dependencies you have to pass these options to it I was running into some issues when deploying to the Lambda but this seemed to fix it if you look at the index.js file you'll see this is all the code that our Lambda runs it uses the AWS S3 SDK to interact with our buckets so we're instantiating a client here we then Define a destination bucket that we get from our environment variables we have a thumbnail width and some supported file formats in the Handler we take in an event and this event will refer to the S3 put object event so when a user uploads an object it'll send our Lambda that event if you're curious how this event looks like we can go back to the console and hit test under template look up S3 and then select S3 put so the event is an object with a Records property which is an array with one object in it on this object we get the event time the name and a lot of other info but what we want is the property under S3 and then the bucket name and also the object key so we need to parse these values from this nested structure that's all that we're doing here we're grabbing the event time and getting the source bucket we're also sanitizing the object key just in case it has any weird characters or spaces so this Source key will have the clean key we're also grabbing the file extension next we log out the event just so we have a reference in our Cloud watch logs if we ever need to debug anything then we check if the file extension is included in our supported formats that we defined up here if it's not included then we're going to log out this error and return out of the function if it was a valid file type then we try to fetch the original file from our source bucket so we call the get object command and that's going to return the image and the content type we take the image body and call it transform to buy array to get an array of bytes which we then pass into sharp which is our file resizer library then we change some methods to resize the image pass again our thumbnail width and call to buffer now we could take this output buffer and store it in our destination bucket so we'll call the put object command pass in the destination bucket for the key will keep it the same as the source key so we could map it over easily and then we're passing the body and content type so this will store this resized image in our destination bucket and if that's a success we're just going to log the successful message and return to 200. so that's it for the Lambda code now we're ready to deploy it all we have to do to deploy is zip up this Handler code and all the function dependencies if you look at the package Json I have a script called package which will zip up our function and dependencies and output it to a file called function.zip so if you wanted to tweak any code all you'd have to do is open up the terminal and run npm run package and that'll package everything up and put it in this ZIP now we just have to take this Sip and upload it to our Lambda we'll close out of that and then hit this upload from we'll select zip file and then we need to find that zip that we just created and we'll hit save once that finishes uploading we need to add an environment variable if you look back at the code you'll see that we Define a destination bucket that we get from the environment so we need to go and add this variable through the console we just need to navigate to the configuration tab and then to environment variables click edit and then we'll add it in here and our destination bucket was demo user thumbnails so I'm just going to paste that in hit save and now our Lambda should be good to go to test our Lambda we can navigate to the test tab under template let's look up S3 and do S3 put then all we have to change is the bucket name my case I want to get demo user images that will store the original images and also replace the RN value here for the key I uploaded an image called Golf Course dot jpeg so I'm going to copy that over for the key now that we have those set it should resize that image so we'll hit test and we see a status 200 with our success message now let's actually go and check that bucket and verify that the image was resized and there we go so the Lambda code is working properly and the last thing we have to do is add a trigger right now this Lambda will never run unless we directly invoke it but what we need to do is add a trigger so that whenever an image is uploaded to the bucket it'll invoke our Lambda and pass in the event so let's add a trigger for the source we'll select S3 for the bucket I'm going to select the user images bucket we don't need a prefix or suffix but if you guys wanted to customize the trigger Behavior you could set values for those and we also have to check this box which basically warns us against recursive invocation this would happen if the input bucket that triggered our Lambda was the same one that the Lambda would write to when it was done because when the Lambda would write to the bucket that would trigger another invocation and that Lambda would write to the same bucket and therefore go in an infinite Loop you can use the same bucket but you'll have to use prefixes for example we could have a prefix called originals and that would store all the original files and the trigger would be under that prefix then when the Lambda resizes the image it would store it in a prefix called thumbnails so when the image is stored under thumbnails it wouldn't trigger another invocation but just to be safe I created two separate buckets and that's what AWS recommends let's click add and test out the trigger we'll go back to our bucket and upload a new image I'll select this tiger and I'll just open up the original image so you can see it there and then in the thumbnails we should see the smaller version there we go so our trigger works properly that's it for this video thank you guys so much for watching leave a like if you enjoyed And subscribe if you haven't already it would help me out a ton let me know in the comments if you have any feedback or what you guys want to see next and I'll see you in the next one foreign [Music]
Info
Channel: Nikita Dev
Views: 2,996
Rating: undefined out of 5
Keywords: javascript, node, aws, aws lambda, aws s3, node lambda, resize images node, image resizer lambda, resize images, aws node, lambda tutorial, aws s3 tutorial, aws lambda tutorial, aws tutorial, programming, programming tutorial, cloud services
Id: QFgJFoS_Hl0
Channel Id: undefined
Length: 13min 11sec (791 seconds)
Published: Tue Sep 26 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.