๐Ÿงฐ DevOps

S3, CloudFront, Lambda@Edge๋ฅผ ์ด์šฉํ•œ ์ด๋ฏธ์ง€ ๋ฆฌ์‚ฌ์ด์ฆˆ(5) - Lambda@Edge ๋ฐฐํฌ ์…‹ํŒ… ๋ฐ ๋กœ๊ทธ ํ™•์ธ

์—ฐ_์šฐ๋ฆฌ 2023. 5. 28. 20:45
๋ฐ˜์‘ํ˜•

๋ชฉ์ฐจ

     

     

     

     

    ์ด ๊ฒŒ์‹œ๊ธ€์€ ์‹œ๋ฆฌ์ฆˆ๋ฌผ์ž…๋‹ˆ๋‹ค!
    ์•„๋ž˜ ๋ชฉ์ฐจ๋ฅผ ๋จผ์ € ํ™•์ธํ•ด์ฃผ์„ธ์š”

    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 ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
     

    Serverless Framework: Plugins

    The Serverless Framework Plugin Registry. Search thousands of Serverless Framework plugins.

    www.serverless.com

    ๋งํฌ๋ฅผ ์ฐธ์กฐํ•ด์„œ๋„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ,
    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
    
    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์ผ๋•Œ๋Š” ๋žŒ๋‹ค๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ๋ณด๋‹ˆ ์ด๋ฒคํŠธ ํƒ€์ž…์— ๋งž๊ฒŒ ์ž˜ ๋™์ž‘ํ•˜๋„ค์š”! 

     

     

     

     

     

     

     

    ๋ฐ˜์‘ํ˜•
    • ๋„ค์ด๋ฒ„ ๋ธ”๋Ÿฌ๊ทธ ๊ณต์œ ํ•˜๊ธฐ
    • ํŽ˜์ด์Šค๋ถ ๊ณต์œ ํ•˜๊ธฐ
    • ํŠธ์œ„ํ„ฐ ๊ณต์œ ํ•˜๊ธฐ
    • ๊ตฌ๊ธ€ ํ”Œ๋Ÿฌ์Šค ๊ณต์œ ํ•˜๊ธฐ
    • ์นด์นด์˜คํ†ก ๊ณต์œ ํ•˜๊ธฐ