Wisdom’s Cloud

[AWS] 1. Lambda@Edge를 사용하여 이미지 리사이징 본문

AWS/Advanced

[AWS] 1. Lambda@Edge를 사용하여 이미지 리사이징

지혜로운지혜쓰 2022. 2. 16. 15:15

Lambda@Edge

  • Lambda@Edge는 CloudFront를 통해 전달되는 콘텐츠를 사용자 지정하는 함수를 실행할 수 있게 해주는 Lambda가 확장된 컴퓨팅 서비스입니다.
  • 서버를 프로비저닝하거나 관리하지 않고 한 리전 US-East-1(버지니아 북부)에서 Node.js 또는 Python 함수를 작성한 후 뷰어에게 가까운 전 세계 AWS 위치에서 해당 함수를 실행할 수 있습니다.
  • 하루 몇 번의 요청에서 초당 수천 개의 요청으로 자동 확장되며, 오리진 서버가 아니라 최종 사용자에게 가까운 AWS 위치에서 요청을 처리하므로 지연 시간이 크게 단축되고 사용자 경험이 상당히 개선됩니다.

 

Lambda@Edge 함수를 트리거할 수 있는 CloudFront 이벤트

출처: https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html

  • Viewer request: CloudFront가 최종 사용자로부터 요청을 수신하면 실행되며, 요청된 객체가 CloudFront 캐시에 있는지를 확인합니다.
  • Origin request: CloudFront가 오리진으로 요청을 전달할 경우에만 실행됩니다. 요청된 객체가 CloudFront 캐시에 저장되어 있으면 이 함수는 실행되지 않습니다.
  • Origin response: CloudFront가 오리진으로부터 응답을 수신한 후 실행되어 응답의 객체를 캐싱합니다. 오리진에서 오류가 반환되는 경우에도 이 함수는 실행됩니다.
  • Viewer response: 요청된 파일을 최종 사용자에게 반환하기 전에 함수가 실행됩니다. 이때 이 함수는 해당 파일이 이미 CloudFront 캐시에 있는지 여부와 상관없이 실행됩니다.

 

 

실습

구성 아키텍처

 

S3 / Route 53 / ACM 생성 및 구성

더보기

S3에 리사이징할 이미지를 저장하기 위해 아래와 같이 구성합니다.

 

S3 콘솔에서 버킷을 선택한 후 버킷 만들기를 클릭합니다.
버킷 이름을 입력하고, 이 버킷에 작성한 객체와 소유권 및 액세스 제어 목록(ALC)의 사용을 제어할 수 있도록 ACL 활성화를 선택합니다.
모든 퍼블릭 액세스 차단을 해제하여 이 버킷과 안에 포함된 객체가 퍼블릭 상태가 될 수 있도록 합니다. 그리고 경고 확인을 체크한 후, 맨 아래 버킷 만들기를 클릭합니다.
생성한 버킷에서 업로드를 클릭합니다.
적당한 이미지 파일을 추가한 후, 업로드를 클릭합니다.
업르드한 이미지의 권한 부분에서 편집을 클릭합니다.
모든 사람이 객체와 객체 ACL에 읽기 권한을 가질 수 있도록 체크하고, 경고 확인을 체크한 후, 맨 아래 변경 사항 저장을 클릭합니다.

더보기

Route 53을 통해 아래와 같이 사용할 도메인을 등록해둡니다.

 

더보기

CloudFront에서 사용할 ACM 인증서를 버지니아 북부에 생성해둡니다. (CloudFront 배포에 ACM 인증서를 할당하려면 버지니아 북부 리전에서만 인증서를 요청하거나 가져올 수 있습니다.)

 

 

CloudFront 생성 및 구성

CloudFront 콘솔에서 배포를 선택한 후, 배포 생성을 클릭합니다.
원본 도메인에 생성한 버킷을 선택하고, 버킷이 CloudFront에 대한 액세스로만 제한하도록 OAI 사용을 체크하여 새 OAI을 생성합니다. 그리고 OAI에 대한 읽기 액세스를 허용하도록 S3 버킷 정책을 업데이트하도록 합니다.
HTTP 요청이 자동으로 HTTPS 요청으로 리디렉션 되도록 뷰어 프로토콜 정책을 설정합니다.
CloudFront로 접속할 대체 도메인 이름을 추가하고, 생성한 ACM 인증서를 선택한 후, 맨 아래 배포 생성을 클릭합니다.
생성한 도메인에서 CloudFront의 대체 도메인 이름을 사용할 수 있도록 레코드를 생성합니다.

 

Lambda 생성 및 구성

버지니아 북부 Lambda 콘솔에서 함수를 선택한 후, 함수 생성을 클릭합니다. (Lambda@Edge는 버지니아 북부에서만 생성할 수 있습니다.)
함수 이름을 입력합니다.
기본 Lambda@Edge 권한을 가지는 새로운 역할을 생성한 후, 함수 생성을 클릭합니다.
생성한 함수의 구성 부분의 권한에서 만든 역할을 클릭합니다.
권한 추가에서 정책 연결을 클릭하여, Lambda 함수가 여러 서비스에 접근 가능하도록 정책 연결 페이지로 접속합니다.
정책 생성을 클릭하여 정책 생성 페이지로 접속합니다.
Lambda@Edge 함수를 CloudFront 배포와 연결하는 데 필요한 IAM 권한을 JSON으로 추가합니다. 아래 더보기의 정책 내용을 붙여넣은 후, 다음을 클릭합니다.

더보기

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceLinkedRole",
                "lambda:GetFunction",
                "lambda:EnableReplication",
                "cloudfront:UpdateDistribution",
                "s3:GetObject",
                "s3:PutObject",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:DescribeLogStreams"
            ],
            "Resource": "*"
        }
    ]
}

 

정책 이름을 입력한 후, 정책 생성을 클릭합니다.
다시 정책 연결 페이지로 돌아와서 새로 고침한 후, 생성한 정책을 선택하고, 정책 연결을 클릭합니다.

 

imageresizing 코드 파일 업로드

imageresizing.zip
0.01MB

더보기

위의 파일을 다운로드 합니다. 그리고 VirtualBox에 Ubuntu를 설치하여 아래의 명령어를 차례대로 실행합니다. (Lambda는 Linux 기반에서 실행되므로 Windows 환경의 Node.js 패키지가 제대로 돌아가지 않을 확률이 높기 때문에 VirturalBox를 통해 Ubuntu에서 진행하였습니다.)

 

# 노드를 설치하기에 앞서 설치에 필요한 커맨드라인 툴을 설치합니다.

~$ sudo apt update

~$ sudo apt-get install curl

 

# apt 패키지 매니저를 통해 우분투 패키지 저장소에 기본으로 들어가 있는 node.js를 다운로드 합니다.

~$ sudo apt install nodejs

 

# 노드 패키지 매니저인 npm을 다운로드 합니다.

~$ sudo apt install npm

 

# 노드 설치가 완료되었는지 확인합니다.

~$ nodejs -v

 

# 작성일(2022.02) 기준으로 노드의 버전이 v16.14.0이라면 안정 버전입니다. 하지만 안정 버전보다 낮은 버전으로 설치되었다면 버전을 업그레이드 합니다.

    # npm 캐시를 제거합니다.

    ~$ sudo npm cache clean -f

    # 노드 버전을 관리할 수 있는 n이라는 모듈을 설치합니다.

    ~$ sudo npm install -g n

    # n 모듈을 사용해 노드를 설치합니다. 

    ~$ sudo n stable 

 

# 다운로드한 파일을 넣을 폴더를 생성합니다.

~$ mkdir nodejs-main

 

# 파일을 수정하기 위해 vim 편집기를 설치합니다.

~$ sudo apt install vim

 

WinSCP를 통해 로컬에서 다운로드한 파일을 생성한 폴더에 전송합니다. ~/nodejs-main 폴더 아래에 imageresizing 폴더가 존재하면 됩니다.

 

# vim 편집기로 index.js 파일을 수정합니다. bucket명을 자신의 버킷 이름으로 변경하면 됩니다.

~/nodejs-main/imageresizing$ sudo vim index.js

 

# index.js 파일에서 사용한 노드 패키지들을 설치합니다. 패키지를 설치하면 node_modules 폴더에 패키지가 설치되면서 package.json 파일에 기록을 합니다.

~/nodejs-main/imageresizing$ sudo npm install querystring

~/nodejs-main/imageresizing$ sudo npm install aws-sdk

~/nodejs-main/imageresizing$ sudo npm install sharp

~/nodejs-main/imageresizing$ sudo npm install heic-convert

 

# 수정된 imageresizing 폴더를 zip으로 압축합니다.

~/nodejs-main/imageresizing$ sudo zip -r ../imageresizing.zip .

 

압축한 파일을 다시 로컬로 전송하면, Lambda에 업로드할 코드 파일이 완성되었습니다.

 

생성한 함수의 코드 부분에서 .zip 파일을 클릭한 후, 압축한 파일을 업로드 합니다.

 

Lambda@Edge 배포

생성한 CloudFront 배포의 동작 부분에서 동작 생성을 클릭합니다.
사용할 경로 패턴을 입력하고, 원본을 생성한 S3 버킷으로 선택한 후, Redirect HTTP to HTTPS를 선택합니다.
캐시 정책을 직접 추가하기 위해 Legacy cache settings를 선택합니다. 그리고 지정된 쿼리 문자열에 이미지 크기를 의미하는 "w"와 "h"를 추가한 후, 맨 아래 변경 사항 저장을 클릭합니다. (품질을 의미하는 "q"와 파일 형식을 의미하는 "f"도 사용할 수 있습니다.)
생성한 함수에서 트리거 추가를 클릭합니다.
CloudFront를 선택하고, Lambda@Edge 배포를 클릭합니다.
CloudFront 이벤트를 오리진 응답으로 선택하고, Lambda@Edge로 배포 확인에 체크한 후, 배포를 클릭합니다.

 

확인

기존 경로로 접속하면, 원래 472x377 사이즈인 이미지를 볼 수 있습니다.
하지만 기존 경로 뒤에 사이즈를 지정하여 접속하면, 이미지가 리사이징된 것을 확인할 수 있습니다.

'AWS > Advanced' 카테고리의 다른 글

[AWS] 2. CloudFront을 사용하여 웹사이트 속도 향상  (0) 2022.03.02