๋ชฉ์ฐจ
์ด ๊ฒ์๊ธ์ ์๋ฆฌ์ฆ๋ฌผ์ ๋๋ค!
์๋ ๋ชฉ์ฐจ๋ฅผ ๋จผ์ ํ์ธํด์ฃผ์ธ์
1. Lambda@Edge๋?
2. S3, CloudFront ์ ํ
3. CloudFront ์ฟผ๋ฆฌ์คํธ๋ง ์บ์ ์ ํ
4. IAM ์ญํ ์์ฑ
5. Lambda@Edge ๋ฐฐํฌ ์ ํ ๋ฐ ๋ก๊ทธ ํ์ธ
6. ๋ฆฌ์ฌ์ด์ง ๋ก์ง ์์ฑ ๋ฐ ํ ์คํธ
ํ๋ก์ ํธ ์ ํ
- serverless framework๋ฅผ ์ฌ์ฉํ์ฌ ๋๋ค๋ฅผ ๋ฐฐํฌํ ์์ ์ ๋๋ค.
- ์ด๋ฏธ ์กด์ฌํ๋ S3์ CloudFront์ Lambda@Edge๋ฅผ ์ฐ๊ฒฐํ๋ฏ๋ก
serverless-lambda-edge-pre-existing-cloudfront ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํฉ๋๋ค.
๋งํฌ๋ฅผ ์ฐธ์กฐํด์๋ ์ค์ ํ ์ ์๋๋ฐ,
CloudFront ๋ฐฐํฌ ๊ตฌ์ฑ๋จ๊ณ์์ ์ฌ์ฉํ๋ "resources: Resources:" ์ค์ ์ ์ฌ์ฉํ๋ฉด
๋๋ค๋ฅผ ๋ฐฐํฌํจ๊ณผ ๋์์ ํด๋ผ์ฐ๋ํ๋ก ํธ๋ ์ ๊ฑฐ๋์๋ค๊ฐ ์๋ก ์์ฑ๋๋ ๊ฒ ๊ฐ์ต๋๋ค....
์์ธํ ์์ธ์ ๋ชจ๋ฅด๊ฒ ๋ค...
Serverless ์ค์น
1. ๋ช ๋ น์ด ์ ๋ ฅ
npm install -g serverless
ํ๋ก์ ํธ ํด๋ ์์ฑ
serverless
- ํ ํ๋ฆฟ : AWS - Node.js - Starter
- ํ๋ก์ ํธ๋ช : serverless-lambda-edge-image-resize
์๋ฒ๋ฆฌ์ค ํ๋ก์ ํธ๋ฅผ ๋ง๋ค๊ณ ๋๋ฉด ์๋์ ๊ฐ์ด 4๊ฐ์ ํ์ผ์ด ์์ฑ๋ฉ๋๋ค.
index.js : ๋๋ค์์ ์ํ๋ ๋น์ฆ๋์ค ๋ก์ง์ด ์์ฑ๋ ํ์ผ
serverless.yml : ๋๋ค ๋ฐฐํฌ ์ ํ์ํ ์ ํ ํ์ผ
node ๋ชจ๋ ๊ด๋ฆฌ๋ฅผ ์ํด npm init ์ํ
npm init
๋ฐฐํฌ ์ ํ
๋๋ค์ ํด๋ผ์ฐ๋ ํ๋ก ํธ๊ฐ ์ ์ฐ๊ฒฐ๋๋์ง ํ์ธํ๊ธฐ ์ํด ๋๋ค์ console.log()๋ง ์ฐ์ด์ ๋ฐฐํฌํด๋ด ๋๋ค.
index.js ์์
serverless.ymlํ์ผ์ provider.runtime์ด nodejs18.x๋ก ๋์ด์๋ค๋ฉด
index.js์ module.exports.handler, require๋ ๋์ด์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ํ package.json์ typeํ๋๊ฐ module๋ก ์ง์ ๋์ด์ผ๋ง ES6๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค.
1. ๋งํฌ ์ฐธ๊ณ ํ์ฌ index.js ์์
2. ์ด๋ค ํจ์์ธ์ง ๋ช ํํ ๋ํ๋ด๊ธฐ ์ํด ํจ์๋ช handler → imageResize๋ก ์์
//node 16 : CommonJS ๋ฐฉ์
exports.imageResize = async function (event, context) { ~ };
//node 18 : ES6 ๋ฐฉ์
export const imageResize = async (event, context) => { ~ };
3. ๋งํฌ ์ฐธ๊ณ ํ์ฌ package.json์ type:module ์ถ๊ฐ
//package.json
{
"name": "serverless-lambda-edge-image-resize",
"version": "1.0.0",
"type": "module",
"description": "<!-- title: 'AWS Simple HTTP Endpoint example in NodeJS' description: 'This template demonstrates how to make a simple HTTP API with Node.js running on AWS Lambda and API Gateway using the Serverless Framework.' layout: Doc framework: v3 platform: AWS language: nodeJS authorLink: 'https://github.com/serverless' authorName: 'Serverless, inc.' authorAvatar: 'https://avatars1.githubusercontent.com/u/13742415?s=200&v=4' -->",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"serverless-lambda-edge-pre-existing-cloudfront": "^1.2.0"
}
}
4. ๋๋คํจ์์ console.log๋ฌธ ์์ฑ
์ค์ ๋ก event๊ฐ์ฒด์ ์ด๋ค ๊ฐ์ด ๋ค์ด์ค๋์ง ํด๋ผ์ฐ๋ ์์น์์ ํ์ธํ ์์ ์ ๋๋ค.
์ฌ๊ธฐ์์๋ ํ์ธํ ์ ์๋ค.
export const imageResize = async (event, context) => {
console.log("serverless-lambda-edge-image-resize ์คํ!");
console.log(JSON.stringify(event));
const res = event.Records[0].cf.response;
return res;
};
ํ๋ฌ๊ทธ์ธ ์ค์น
- ๋ช ๋ น์ด ์ ๋ ฅํ์ฌ ์ค์น
npm install --save-dev serverless-lambda-edge-pre-existing-cloudfront
- serverless.yml๋ ํ๋ฌ๊ทธ์ธ์ ๊ฐ์ด๋๋๋ก ์์ ํด์ค๋๋ค.
#serverless.yml
service: serverless-lambda-edge-image-resize
frameworkVersion: '3'
plugins:
- serverless-lambda-edge-pre-existing-cloudfront
provider:
name: aws
runtime: nodejs18.x
region: us-east-1 #lambda@edge๋ ๋ถ๋ฏธ์๋ฒ์๋ง ๋ฑ๋ก ๊ฐ๋ฅํ๋ค.
iam:
role: 'arn:aws:iam::~'
functions:
imageResize:
name: 'serverless-lambda-edge-image-resize'
handler: index.imageResize #index.js ํ์ผ์ imageResize ํจ์๋ฅผ ๋ฐ๋ผ๋ณธ๋ค
events:
- preExistingCloudFront:
distributionId: E3AICXLJSBYDFW #s3-lambda-edge-image-resize์ cloudfront id๊ฐ ์
๋ ฅ
eventType: origin-response
pathPattern: '*'
includeBody: false
- provider > iam > role : ๋๋ค๊ฐ ์คํ๋ ์ ์๋๋ก ์ด์ ์ ๋ง๋ค์๋ iam์ arn์ ์ ๋ ฅํฉ๋๋ค.
- handler > index.Resize : index.jsํ์ผ์ imageResizeํจ์๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ ๋ ฅํฉ๋๋ค.
- events > preExistingCloudFront
- distributionId : ์ด์ ์ ๋ง๋ค์๋ cloudfront์ id๊ฐ์ ์ ๋ ฅํฉ๋๋ค.
- eventType: origin-response๋ฅผ ์ ๋ ฅํด๋์์ผ๋ ์บ์ฑ์ฒ๋ฆฌ๋์ง ์์ ์ด๋ฏธ์ง๋ฅผ ํธ์ถํ ๋ ๋๋ค๊ฐ ํธ์ถ๋ฉ๋๋ค. eventType์ ๋ํ ๋ ์์ธํ ๋ด์ฉ์ ๋งํฌ๋ฅผ ์ฐธ์กฐํด์ฃผ์ธ์.
๋ฐฐํฌ
- ๋ฐฐํฌ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ๊ณ ๊ธฐ๋ค๋ฆฌ๋ฉด 2๋ฒ์งธ ์ฌ์ง์ฒ๋ผ ์ฑ๊ณต ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค.
serverless deploy
- ๋ฒ์ง๋์ ๋ถ๋ถ๋ฆฌ์ > Lambda > ํจ์ > serverless-lambda-edge-image-resize
- ๋ฒ์ > ์ต์ ๋ฒ์ ํด๋ฆญ
- ๊ฐ์ฅ ์ต์ ๋ฒ์ ์ ํธ๋ฆฌ๊ฑฐ๋ก CloudFront๊ฐ ์กํ์๋์ง ํ์ธ
ํ ์คํธ
F12๋ฅผ ๋๋ฌ ๊ฐ๋ฐ์๋๊ตฌ๋ฅผ ์ผ๋๊ณ , ์ฐ๋ฆฌ๊ฐ ์ฐ๊ฒฐํ ํด๋ผ์ฐ๋ ํ๋ก ํธ๋ก ์ด๋ฏธ์ง ํ์ผ์ ํธ์ถํ๋ฉด ๋๋ค๊ฐ ์ํ๋๋์ง ํ์ธํด๋ด ์๋ค.
* ๋ง์ฝ X-Cache๊ฐ Hit from cloudfront๋ก ๋์ด์๋ค๋ฉด, ํด๋ผ์ฐ๋ํ๋ก ํธ๋ก ํ๋ฒ๋ ํธ์ถํ์ง ์์ ์ด๋ฏธ์ง ํ์ผ์ ํธ์ถํด์ฃผ์ธ์.
Miss๋ก ์๋ต๋ฐ์์ผ๋ ํด๋ผ์ฐ๋์์น์์ ๋ก๊ทธ๋ฅผ ํ์ธํฉ๋๋ค.
ํด๋ผ์ฐ๋์์น ๋ก๊ทธ ํ์ธ
์ ๊ฐ ๊ฐ์ฅ ํด๋งจ ๋ถ๋ถ ์ค ํ๋์ ๋๋ค,... ๋ ํฌ๊ฒ ๋จ๊ณ ๋ด์ฃผ์ธ์
๋ก๊ทธ ์ ์ฅ๋๋ ๋ฆฌ์ ์ฃผ์
๊ธฐ์กด์ ๋๋ค๋ฅผ ์ฌ์ฉํด๋ณด์ ๋ถ๋ค์ด๋ผ๋ฉด ๋๋ค ํจ์์ "ํ ์คํธ" ๋ฉ๋ด์ ๋ํด ์๊ณ ๊ณ์ค๊ฒ๋๋ค.
์์ฒ๋ผ ํ ํ๋ฆฟ์ cloudfront-modify-querystring์ผ๋ก ์ ํํ๊ณ ํ ์คํธ๋ฒํผ์ ๋๋ฅด๋ฉด
์คํ ์ฑ๊ณต์ผ๋ก ๋จ๋ฉฐ ๋ก๊ทธ๋ฅผ ๋ณผ์์๋ ๋งํฌ๊ฐ ๋์ค๋๋ฐ, ํด๋น ๋ก๊ทธ๋ ๋ฒ์ง๋์ ๋ฆฌ์ ์ ์ ์ฅ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
(์ด๋ฒคํธ JSON์ ์๋ uri๋ /test๋ก ๋์ผํจ)
ํ์ง๋ง CloudFront๋ฅผ ํตํด ์ํ๋ ๋๋ค์ ๋ก๊ทธ๋... ์์ธ๋ฆฌ์ ์ ์ ์ฅ๋ฉ๋๋ค.
์๊ฐํด๋ณด๋ฉด ๋น์ฐํฉ๋๋ค
๋๋ค์ฃ์ง๋ ๋ฒ์ง๋์ ๋ฆฌ์ ์ ๋ง๋ค์ด๋๋ฉด AWS๊ฐ ์ ์ธ๊ณ ๋ฆฌ์ ์ ์๋์ผ๋ก ๋ณต์ฌํด์ฃผ๊ณ ,
ํด๋ผ์ฐ๋ ํ๋ก ํธ๋ ๋ด ์์น์์ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ฆฌ์ ์์ ์คํ๋ ํ ๋..
๋๋ค์ฃ์ง๋ ๋ด ์์น์์ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ฆฌ์ ์์ ์คํ๋๊ฒ ์ฃ !
๊ณต์๋ฌธ์ ์๋ ๋์์์ต๋๋ค
Miss์ Hit์ ๋ฐ๋ฅธ ๋ก๊ทธ ์ถ๋ ฅ ํ์ธ
์ด์จ๋ ์์์ ํธ์ถํ /lucy.jpg์ ๋ํ ๋ก๊ทธ๊ฐ ์ฐํ์์ผ๋ฉด ๋๋ค๊ฐ ์ ์ํ๋๊ฒ์ ๋๋ค.
ํน์ ๋ชจ๋ฅด๋ ๋ค์ํ๋ฒ /lucy.jpg๋ฅผ ํธ์ถํด๋ด ์๋ค
์ด๋ฒ์ Hit์ด ๋ด์ผ๋ ๋๋ค๊ฐ ์ํ๋๋ฉด ์๋ฉ๋๋ค. ํด๋ผ์ฐ๋ ์์น์ ๋ก๊ทธ๊ฐ ์ฐํ๋์ง ๋ด ์๋ค.
Miss์ผ๋๋ง ๋๋ค๊ฐ ์คํ๋๊ณ , Hit์ผ๋๋ ๋๋ค๊ฐ ์คํ๋์ง ์๋ ๊ฒ์ ๋ณด๋ ์ด๋ฒคํธ ํ์ ์ ๋ง๊ฒ ์ ๋์ํ๋ค์!