[AWS] Cloudfront: Function

Cloudfront Function์€ Cloudfront์—์„œ ์š”์ฒญ์ด๋‚˜ ์‘๋‹ต์„ ๊ฐ€๋กœ์ฑ„์„œ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ์—ฃ์ง€ ์ˆ˜์ค€ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์ด๋‹ค.

Lambda Edge์™€๋„ ๋น„์Šทํ•œ ๋А๋‚Œ์œผ๋กœ ๋™์ž‘ํ•˜๋‚˜, ์กฐ๊ธˆ ๋‹ค๋ฅด๋‹ค.

**Lambda Edge **

  1. Lambda Edge๋Š” ์ด๋ฏธ์ง€ ์ตœ์ ํ™” ๊ฐ™์€ ์ƒ๋‹นํžˆ ๋ฌด๊ฑฐ์šด ์—ฐ์‚ฐ์„ ํฌํ•จํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ• ๋•Œ ์ ํ•ฉํ•˜๋‹ค.

  2. ์‘๋‹ต์ด๋‚˜ ์š”์ฒญ ๋“ฑ ๋‹ค์–‘ํ•œ ์‹œ์ ์— ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ , ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚˜๋‹ค.

  3. ๊ทธ๋Œ€์‹  ๋ฌด๊ฒ๊ณ  ๋น„์‹ผ ํŽธ์ด๋‹ค.



Cloudfront Function

  1. Function์€ ๊ฐ„๋‹จํ•œ HTTP ์‘๋‹ต ํ—ค๋” ์กฐ์ž‘์ด๋‚˜ ๋ฆฌ๋””๋ ‰์…˜ ๊ฐ™์€ ๋งค์šฐ ๊ฐ€๋ฒผ์šด ์กฐ์ž‘์— ์ ํ•ฉํ•˜๋‹ค.

  2. ๋งค์šฐ ์ž‘์€ ์ฝ”๋“œ๋งŒ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๊ณ , ์ œํ•œ์ ์ธ ๋Œ€์‹ ์— ๋น ๋ฅด๊ณ , ํ›จ์”ฌ ๋งŽ์€ ์—ฃ์ง€์— ๋ฐฐํฌ๋˜์–ด ๋ฌผ๋ฆฌ์ ์œผ๋กœ๋„ ๋น ๋ฅด๋‹ค. 1๋ฐ€๋ฆฌ์ดˆ ๋ฏธ๋งŒ์˜ ์‹คํ–‰์‹œ๊ฐ„์„ ๋ณด์žฅํ•œ๋‹ค.

  3. ๋น„์šฉ์ด ์ €๋ ดํ•˜๋‹ค.



์•„๋ž˜๋Š” ์ฐจ์ด์ ์„ ๋น„๊ตํ•œ ๋„ํ‘œ๋‹ค.

https://aws.amazon.com/ko/blogs/aws/introducing-cloudfront-functions-run-your-code-at-the-edge-with-low-latency-at-any-scale/





๋น„์šฉ

https://aws.amazon.com/ko/cloudfront/pricing/


๋น„์šฉ์€ ์ €๋ ดํ•œ ํŽธ์ด๋‹ค. ๋‹จ์ˆœํžˆ ํšŸ์ˆ˜๋กœ๋งŒ ๋น„์šฉ์„ ๋ถ€๊ณผํ•œ๋‹ค.
100๋งŒ๊ฑด๋‹น 0.1 ๋‹ฌ๋Ÿฌ๋ฅผ ๋œฏ๋Š”๋‹ค.




์˜ˆ์ œ: ๋‹ค๊ตญ์–ด ์ฒ˜๋ฆฌํ•˜๊ธฐ

Cloudfront ํ—ค๋”์™€ Function ๊ธฐ๋ฐ˜์˜ ๋ฆฌ๋””๋ ‰์…˜์„ ์‘์šฉํ•ด์„œ ๋‹ค๊ตญ์–ด ๋ผ์šฐํŒ…์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์ด๊ฒ ๋‹ค.
์—ฌ๊ธฐ์„œ๋Š” ๋ทฐ์–ด ์š”์ฒญ ํŠธ๋ฆฌ๊ฑฐ๋งŒ์„ ์‘์šฉํ•ด์„œ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๊ตณ์ด ์˜ค๋ฆฌ์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ์ „์—๋„ URI๋‚˜ ๊ตญ๊ฐ€ ์ •๋ณด๋Š” ๋‹ค ์•Œ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์˜ค๋ฆฌ์ง„์—์„œ ๋ฐ˜ํ™˜๋œ ์‘๋‹ต ํ—ค๋”๊ฐ™์€๊ฑธ ์กฐ์ž‘ํ•  ์ผ์ด ์—†๋‹ค๋ฉด ๋ทฐ์–ด ์š”์ฒญ ํŠธ๋ฆฌ๊ฑฐ๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜๋‹ค.


1. ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ

๋จผ์ € Cloudfront ์ฝ˜์†”๋กœ ์ด๋™ํ•ด์„œ

Function ํƒญ์— ์ง„์ž…

์ƒ์„ฑ์ฐฝ์œผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค.

์ด๋ฆ„ ์ ๋‹นํžˆ ์ง“๊ณ  ๋งŒ๋“ค๋ฉด ๋œ๋‹ค.


์ด๋ ‡๊ฒŒ ๋œจ๋ฉด ๋œ ๊ฒƒ์ด๋‹ค.



2. ํ•จ์ˆ˜ ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

Function ์ฝ˜์†”์— ๋“ค์–ด๊ฐ€๋ฉด AWS Lambda ์ฒ˜๋Ÿผ ์ž์ฒด์ ์ธ ์—๋””ํ„ฐ๋ฅผ ๋ฐ”๋กœ ์ œ๊ณตํ•œ๋‹ค. ๊ทธ๋ฆฌ ํŽธํ•˜์ง„ ์•Š์ง€๋งŒ

๊ฐœ๋ฐœ, ๋ผ์ด๋ธŒ 2๊ฐœ์˜ ์Šคํ…Œ์ด์ง€๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•œ๋‹ค.

๋จผ์ € ๊ฐœ๋ฐœ ์ฝ”๋“œ์—๋‹ค๊ฐ€ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ง‘์–ด๋„ฃ์ž.

function handler(event) {
  const request = event.request;

  const supported_countries = ["de", "it", "fr", "kr"];

  if (request.uri.substr(3, 1) != "/") {
    const headers = request.headers;

    let newUri;

    const country = headers["cloudfront-viewer-country"];

    if (country) {
      const countryCode = country.value.toLowerCase();
      if (supported_countries.includes(countryCode)) {
        newUri = "/" + countryCode + request.uri;
      }
    }
    if (newUri === undefined) {
      const defaultCountryCode = "en";
      newUri = "/" + defaultCountryCode + request.uri;
    }
    const response = {
      statusCode: 302,
      statusDescription: "Found",
      headers: {
        location: { value: newUri },
      },
    };
    return response;
  }
  return request;
}

๋กœ์ง์€ ๊ทธ๋ฆฌ ๋ณต์žกํ•˜์ง€ ์•Š๋‹ค.

  1. ์ด๋ฏธ ๋‹ค๊ตญ์–ด ๋ผ์šฐํŒ…์ด ๋œ /de... ๊ฐ™์€ ๊ฒฝ๋กœ๋ผ๋ฉด request.uri.substr(3, 1) != "/"์— ๊ฑธ๋ ค์„œ ๋ฆฌ๋””๋ ‰์…˜ ์—†์ด ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์•„๋‹ˆ๋ผ๋ฉด ๋‹ค๊ตญ์–ด ๋ผ์šฐํŒ… ์‹œ๋„ํ•œ๋‹ค.
  2. Cloudfront์—์„œ ์ž์ฒด์ ์œผ๋กœ ๊ตญ๊ฐ€๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ›๋Š” cloudfront-viewer-country๋ผ๋Š” ํ—ค๋”๋ฅผ ๊ฐ€์ ธ๋‹ค๊ฐ€, ๊ตญ๊ฐ€๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค. ๊ตญ๊ฐ€์ฝ”๋“œ๋Š” ISO ํ‘œ์ค€์— ๊ธฐ๋ฐ˜ํ•œ๋‹ค.
  3. ๊ตญ๊ฐ€์ฝ”๋“œ๊ฐ€ ์—†๊ฑฐ๋‚˜ ๋ชจ๋ฅด๋Š”๊ฑฐ๋ฉด ์˜์–ด /en๋กœ ๋ผ์šฐํŒ…ํ•œ๋‹ค.
  4. ๊ทธ๋ ‡๊ฒŒ ํ•ด์„œ ๋…์ผ, ์ดํƒœ๋ฆฌ, ๋ถˆ๋ž€์„œ, ํ•œ๊ตญ์ด ๋“ค์–ด์˜ค๋ฉด /kr/, /de/, ... ๊ฐ™์€ ๊ฒฝ๋กœ๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•˜๋„๋ก ๊ตฌ์„ฑํ•œ ๊ฒƒ์ด๋‹ค. (location ํ—ค๋” ํ™œ์šฉ)

์—ฌ๊ธฐ์„œ๋Š” location์œผ๋กœ ๋– ๋„˜๊ฒจ์„œ uri๊นŒ์ง€ ๋ณ€๊ฒฝ๋˜๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ทจํ–ˆ์ง€๋งŒ, request.uri๋ฅผ ๋ณ€๊ฒฝํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฆฌ๋””๋ ‰์…˜ ์—†์ด S3 ์˜ค๋ฆฌ์ง„๋งŒ ๋ฐ”๋€ ์ฑ„ ๋™์ผํ•œ uri๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

์•„๋ฌดํŠผ ์ €๋ ‡๊ฒŒ ๋„ฃ์–ด์„œ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ €์žฅํ•˜๊ณ , ํ…Œ์ŠคํŠธ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•ด์„œ ์ž˜ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž.

๋Œ€์ถฉ ์•„๋ฌด๊ฒƒ๋„ ์•ˆ๋„ฃ์—ˆ์„๋•Œ๋Š” /en๋กœ ๋˜์ ธ์ฃผ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๊ณ 


๋„ฃ์–ด์„œ ์˜๋ฉด ๋„ฃ์€๋Œ€๋กœ ๋‚˜์˜ฌ ๊ฒƒ์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ฒŒ์‹œ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ ๋ผ์ด๋ธŒ๋กœ ๋ฐฐํฌํ•˜๋ฉด ๋์ด๋‹ค.



3. ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๊ตฌ์„ฑํ•˜๊ธฐ (S3, Cloudfront)

์ผ๋‹จ Function์€ ๋ณด์กฐ์ ์ธ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์— ๋ถˆ๊ณผํ•˜๊ณ , ํ™•์ธ์„ ์œ„ํ•ด์„œ๋Š” ํ…Œ์ŠคํŠธ์…‹์„ ์„ธํŒ…ํ•ด์•ผ ํ•œ๋‹ค.

๋จผ์ € ๋‹ค๊ตญ์–ด์— ํ•ด๋‹นํ•˜๋Š” index.html ํŒŒ์ผ๋“ค์„ s3 ๋ฒ„ํ‚ท์— ์˜ฌ๋ ค๋’€๋‹ค.

์ด์ •๋„๋กœ

Cloudfront ์บ์‹œ์„ค์ •๋„ ์ข€ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•œ๋‹ค.
cloudfront-viewer-country๋ผ๋Š” ํŠน์ˆ˜ ํ—ค๋”๋ฅผ Cloudfront๊ฐ€ ์˜ค๋ฆฌ์ง„์— ์ „๋‹ฌํ•ด์ค˜์•ผ ๊ทธ๊ฑธ Function์ด ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”๊ฑด๋ฐ, ๊ธฐ๋ณธ ์บ์‹œ ์„ค์ •์€ ํ—ค๋”๋ฅผ ์ „๋ถ€ ์”น๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทผ๋ฐ ์™„์„ฑํ˜•์œผ๋กœ ์ œ๊ณตํ•ด์ฃผ๋Š” ์ •์ฑ… ์ค‘์— cors ์„ค์ •๊ณผ cloudfront ํ—ค๋” ์„ค์ •์ด ๋™์‹œ์— ๋“ค์–ด์žˆ๋Š”๊ฒŒ ์—†์–ด์„œ ๋˜ ์ง์ ‘ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ์งœ์ฆ์ด ๋‚œ๋‹ค.

์ •์ฑ… > ์›๋ณธ ์š”์ฒญ์œผ๋กœ ์ด๋™


์ •์ฑ…์„ ์ด๋ ‡๊ฒŒ ์ ๋‹นํžˆ ๋งŒ๋“ค์–ด์ค€๋‹ค.
๋‹น์žฅ ํ•„์š”ํ•œ Cloudfront Viewer Country ํ—ค๋”์™€ S3 ์ ‘๊ทผ์— ํ•„์š”ํ•œ CORS ์ „์šฉ ํ—ค๋”๋‹ค. ํ—ค๋”๋ฅผ ์•„๋ฌด๊ฒƒ๋„ ๋„˜๊ธฐ์ง€ ์•Š์„ ๋•Œ๋Š” CORS๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„์„œ ๊ดœ์ฐฎ์€๋ฐ, ์ปค์Šคํ…€ ํ—ค๋”๋ฅผ ๋ณด๋‚ด๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ๋ผ์›Œ์ค˜์•ผ ํ•˜๋”๋ผ.

"๋™์ž‘"์˜ ํŽธ์ง‘์ฐฝ์œผ๋กœ ์ด๋™ํ•ด์„œ

๋ฐฉ๊ธˆ ๋งŒ๋“  ์š”์ฒญ ์ •์ฑ…์„ ๋ผ์›Œ์ฃผ๊ณ 

ํ•จ์ˆ˜๋„ ๋ทฐ์–ด ์š”์ฒญ์—๋‹ค๊ฐ€ ๋„ฃ์–ด์ค€๋‹ค.

์ด๋Ÿฌ๋ฉด ์„ธํŒ…์ด ๋‹ค ๋œ ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ํ•œ๊ตญ์—์„œ ์ ‘๊ทผํ•  ๋•Œ๋Š”

ํ•œ๊ตญ์–ด ๋ฒ„์ „์œผ๋กœ ๋ผ์šฐํŒ…๋  ๊ฒƒ์ด๊ณ 

๋ฏธ๊ตญ์—์„œ ์ ‘๊ทผํ•˜๋ฉด

์˜์–ด

๋ถˆ๋ž€์„œ์—์„œ ์ ‘๊ทผํ•˜๋ฉด

๋ถˆ์–ด ๋ฒ„์ „์œผ๋กœ ๋  ๊ฒƒ์ด๋‹ค.

์ด๋Ÿฐ ๋А๋‚Œ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.



์ฐธ์กฐ
https://aws.amazon.com/ko/blogs/aws/introducing-cloudfront-functions-run-your-code-at-the-edge-with-low-latency-at-any-scale/
https://stackoverflow.com/questions/48633610/how-do-i-get-cloudfront-viewer-country-to-appear-in-response-headers