From e2d60ef31de61ed91f428b8c582f5cdaabded4bc Mon Sep 17 00:00:00 2001 From: Sagid Date: Sun, 10 Sep 2017 03:05:26 +0300 Subject: [PATCH] Update README.md The full description of creating lambda --- README.md | 177 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 144 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 0bedf04..fb9c491 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,56 @@ -Static website hosting -```xml - - - - - 404 - - - https - __DOMAIN__ - __PATH_TO_LAMBDA__?path= - 307 - - - -``` +## What is it? +It's AWS Lambda, which is a compute service that lets you run code without provisioning or managing servers. +> _[Read more about AWS Lambda.](http://docs.aws.amazon.com/lambda/latest/dg/welcome.html)_ -Bucket policy -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "AddPerm", - "Effect": "Allow", - "Principal": "*", - "Action": "s3:GetObject", - "Resource": "arn:aws:s3:::__BUCKET_NAME__/*" - } - ] -} -``` +## What this lambda provides +Let's say we have some _shared image_ in **S3**, for example: +`https://example.com/images/pretty_photo.jpg` + +to resize this image to _150x150_, for instance, on fly we can make a request like this: +`https://example.com/images/150x150/pretty_photo.jpg` + +So, if there's not image in this path, it's redirected to lambda and, after a moment, lambda creates the suitable image and then redirects back. We'll obviously have a new image next time. -Role policy document +*** +Instead of `WxH` there're some extra available _magic paths_: +`.../AUTOx150/...` +`.../150xAUTO/...` +or +`.../150x150_max/...` +`.../150x150_min/...` + +> Note that **s3-resizer** **don't enlarge an image** if the original image width or height are already less than required dimensions. You can read about **[#withoutEnlargement](http://sharp.dimens.io/en/stable/api-resize/#withoutenlargement)** method. + + +## Setting up + +#### To resize images we need a storage, which is _S3_, and _Lambda_ function. Then we should set up redirection rules. + +* Create a **Bucket** +* * Go to [Services -> Storage -> S3](https://s3.console.aws.amazon.com/s3/home) +* * Click on the blue button **Create bucket** +* * Enter the name and click on **Create** + +* Create a **Lambda** +* * Go to [Services -> Compute -> Lambda](https://console.aws.amazon.com/lambda/home) +* * Click on the orange button **Create a function** +* * In the next page, click on the similar button **Author from scratch** +* * Add a trigger, which would listen to http requests (you also would be able to do it later) +* * * On the dotted square choose **API Gateway** +* * * You can use default **API name** or create new one +* * * In **Security** select **Open**, then click **Next** +* * In **Configure function** page +* * * Name a new lambda +* * * In **Runtime** select **Node.js 6.10** +* * * Upload a _.zip_ file (download it from [releases](https://github.com/kofon95/s3-resizer/releases)) +* * * > You'll also need to set up two **Environment variables**, with _BUCKET_ and _URL_ as keys. But in this time, you don't know about that _URL_. It is **endpoint** which you'll see below. +* * * Choose role which has permission to put any object or create a new one. To do that +* * * * choose **Create a custom role** in role's list. It should open a new page in your browser. On that page +* * * * choose **Create a new IAM Role** +* * * * name you role, for example: *"access_to_putObject"* +* * * * Expand **View Policy Document**, click **Edit**, and write this content: ```json { "Version": "2012-10-17", @@ -56,3 +72,98 @@ Role policy document ] } ``` +> Pay attention to `__BUCKET_NAME__` + +* * * That page should closes after that action. So go on creating a lambda. And take a look at **Advanced settings** +* * * * Allocate a memory 512 +* * * * Timeout could be 5 seconds +> It's mooore than enough. And you shouldn't care of limits because images caches, which means lambda calls only for the first time. +* * * Click **Next**, **Create function**. And wait for 20-30 seconds. Lambda is created. + +*** + +* Public access to files in your bucket and relationships between lambda and bucket. +* * Firstly, you need Lambda's _url_ +* * * Click the link of **API name** (in case you didn't change it in creating lambda, it should name like **LambdaMicroservice**) +* * * On the new page, look for **Actions** button, select **Deploy API** and choose **prod** in **Deployment stage**. Then click **Deploy** +* * * Expand **prod** in **Stages**, click on **GET** and copy URL that you see +* * Open your created bucket -> Permissions -> Bucket Policy +* * Paste this pease of code there and click **Save** +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "AddPerm", + "Effect": "Allow", + "Principal": "*", + "Action": "s3:GetObject", + "Resource": "arn:aws:s3:::__BUCKET_NAME__/*" + } + ] +} +``` +> Pay attention to `__BUCKET_NAME__`. By the way, you're able to open access not to whole bucket but to specific directory specifying it instead of __*__. +* * Go to Properties (near to Permissions) -> Static website hosting -> Select **"Use this bucket to host a website"** +* * In **Index document** paste any file, it'd be logical to name it _"index.html"_ +* * Paste this **Redirection rules** +```xml + + + + + 404 + + + https + __DOMAIN__ + __PATH_TO_LAMBDA__?path= + 307 + + + +``` +> Pay attention to `__DOMAIN__` and `__PATH_TO_LAMBDA__` (protocol is always _https_) +> For example, lambda's url is `https://some-id.execute-api.us-east-1.amazonaws.com/prod/your-lambdas-name`, the correct xml nodes must looks like +```xml +some-id.execute-api.us-east-1.amazonaws.com +prod/your-lambdas-name?path= +``` +* * At this state, copy your **Endpoint** and click save +* * Go to your lambda -> **Code** and set up these two **Environment variables** _(format: key=value)_ +**BUCKET**=_your bucket's name_ +**URL**=**Endpoint** you copied before +* * **Save** it. You've done! + +*** + +* Test your lambda (optional) +* * Upload an image to your bucket and copy link to it. Check if the image shows in your browser +> Attention. That link must be of your **Endpoint** (website hosting). It make by concatinating **"$endpoint_url/$path_to_image/$image_name"** +* * Go to lambda, click on **Test**, and paste this json: +```json +{ + "queryStringParameters": {"path": __YOUR_IMAGE_PATH_WITH_SIZE_PREFIX__} +} +``` +> `__YOUR_IMAGE_PATH_WITH_SIZE_PREFIX__` - for example: `150x150/pretty_image.jpg` + +* * Go back to the bucket, a new directory _150x150_ must be created + + +## Some patterns +This is some pattern which you can use in the models: +```ruby +IMAGE_PATH = "#{YOUR_ENDPOINT_URL}/uploads/images/models/" + +def images() + img = self.image_name + + return { + original: "#{IMAGE_PATH}#{img}", + big: "#{IMAGE_PATH}1000x1000_max/#{img}", + small: "#{IMAGE_PATH}450x450_max/#{img}", + thumb: "#{IMAGE_PATH}128x128_max/#{img}" + } +end +```