When developing an application it is important to have assets resized for different capabilities, screen sizes, and resolutions. This is important for many reasons. Low resolution images on high resolution displays make a bad UX High resolution images on low resolution displays waste both and device and server bandwidth resources Creating several thumbnails during image upload, can be a and for future redesigns. lot of work limits the agility Adopting an image in-app and it may be heavy for the app especially if you use Frameworks. cropping/resizing Resizing on the fly Instead of processing and resizing images into all necessary sizes upon upload, the approach of processing images on the fly has several upsides: Increased agility Reduced storage costs Resilience to failure In this post, we’ll be using a different approach and outline a method of lazily generating images, in which a resized asset is only created if a user requests that specific size. Creating a new bucket Open s3 console You can or use existing one but make sure the bucket’s read access permission is set to public. create new bucket Create new bucket, uncheck Block all public access Go to tab then choose permissions bucket policy To grant read-only permission to an anonymous user. Copy and paste this configuration to your bucket policy. Make sure to replace with the name of the bucket. You can read about bucket policy more in YOUR_BUCKET_NAME_HERE here { : , : [ { : , : , : , : , : } ] } "Version" "2012-10-17" "Statement" "Sid" "PublicRead" "Effect" "Allow" "Principal" "*" "Action" "s3:GetObject" "Resource" "arn:aws:s3:::YOUR_BUCKET_NAME_HERE/*" 6. Choose save Go to properties tab Choose static web hosting Choose use this bucket to host a website For , enter index.html index document Choose save. We’ll come later and add but for now just leave it empty. redirection rule Note the website’s endpoint* Creating CloudFront distribution for SSL Open CloudFront console Choose create distribution Choose web distribution Enter the that was noted previously, for static website’s endpoint origin domain name For viewer protocol policy — choose Redirect HTTP to HTTPS For object chaching set and TTL to 0 and TTL to 31536000 choose customize minimum default maximum Rest of the configuration you can leave as it is. You can now choose create distribution This can take few mins, wait until the status changes from ‘in progress’ to ‘deployed’. After the status is changed to deployed, note the CloudFront domain name. It should look similar to blabla .cloudfront.net Setting up permission for Lambda function Open IAM console Creating policy: In the IAM console select from the dashboard to the left Policies Choose create policy Navigate to tab JSON Replace with the name of the bucket that you’ve created and copy the following code into the policy document. Note that any leading spaces in your policy may cause a validation error. YOUR_BUCKET_NAME_HERE { : , : [ { : , : [ , , ], : }, { : , : , : } ] } "Version" "2012-10-17" "Statement" "Effect" "Allow" "Action" "logs:CreateLogGroup" "logs:CreateLogStream" "logs:PutLogEvents" "Resource" "arn:aws:logs:*:*:*" "Effect" "Allow" "Action" "s3:PutObject" "Resource" "arn:aws:s3:::__YOUR_BUCKET_NAME_HERE__/*" Choose review policy Enter your policy name You can use any name but just for simplicity we’ll use the name imageResizePolicy Create policy Creating role: In the IAM console select from the dashboard to the left Roles Select create role Choose in for a use case, Lamda next In permission section search for the that you just created and choose that, You can skip the tags section and choose imageResizePolicy next Next In review section, enter role name, you can use any name but for the sake of simplicity we’ll be using the name imageResizeRole Create role Creating Lambda function Open Lambda console In the lambda console choose create function For function name enter your function name, now of course you can choose any name for just to be safe use as your function name. So that it’ll be easy for you to follow along. imageResize Choose as a runtime. Again you can choose any other language but we’re going to choose Node. You don’t need to worry about it as this lamba function works completely independent from your application. The only purpose it’ll serve is to provide you with resized images on fly. Node.js 12.x Expand the permission dropdown and select . use existing role Select imageResizeRole Choose create function Now choose and select from the dropdown add trigger API Gateway For choose API type HTTP API To allow all users to invoke the API method, for , choose and then . Security Open Add Now back to the main function window, you’ll see section. function code For code entry type choose upload a zip file Download function.zip file from this and upload the zip file, from top right corner link choose save To configure your function environment variables add two variables: For key, and enter for value, enter the bucket name that you created above. BUCKET; For key, enter ; for enter the domain the you created above from CloudFront, similar to URL value blabla.cloudfront.net On the main function window, choose API gateway and scroll a bit till you see our function’s API endpoint. Note the full path of the endpoint, depending upon your personal configuration these might be slightly different. Setting up S3 redirection rule Ok we’re almost there, phew that was a lot of configurations. In s3 console, open the bucket that you created above. To to properties and expand static website hosting, edit redirection rules. Replace (similar to ) with the hostname that you noted above and copy the following into redirection rules configuration. YOUR_API_HOSTNAME_HERE blabla.execute-api.us-east-1.amazonaws.com Notice the path inside <ReplaceKeyPrefixWith> tag, it’s the same from the one we noted above in picture. If your path is different the update it with your path. <RoutingRules> <RoutingRule> <Condition> <KeyPrefixEquals/> <HttpErrorCodeReturnedEquals> </HttpErrorCodeReturnedEquals> </Condition> <Redirect> <Protocol>https</Protocol> <HostName>__YOUR_API_HOSTNAME_HERE</HostName> <ReplaceKeyPrefixWith>default/imageResize?key=</ReplaceKeyPrefixWith> <HttpRedirectCode> </HttpRedirectCode> </Redirect> </RoutingRule> </RoutingRules> 404 307 Test image resizing Upload a test image into your bucket to for testing. Once uploaded, try to retrieve resized versions of the image using your CloudFront domain: https://YOUR_CLOUDFRONT_DOMAIN/300×300/{image_name.jpg} https://YOUR_CLOUDFRONT_DOMAIN/25×25/{image_name.jpg} https://YOUR_CLOUDFRONT_DOMAIN/500×500/{image_name.jpg} You should see a smaller version of the test photo. If not, choose Monitoring in your Lambda function and check CloudWatch Logs for troubleshooting. You can also refer to the GitHub repo for a working example that you can deploy to your account. serverless-image-resizing YOU MADE IT!!! 🚀🎉🎊 Previously published at https://medium.com/@lamamanjil/image-resize-on-fly-with-amazon-s3-aws-lambda-and-cloudfront-for-ssl-8ab046ccf79f