Cloud Front, Lambda Edge, 배포 방식
배경
이미지, 영상 등을 처리하는 Lambda 함수를 사용하면서 Lambda@Edge도 함께 처리했다. Lambda@Edge(이하 엣지)는 Cloud Front(CF) 뒤에 있으면서 전 세계 글로벌 엣지 위치에 실제 물리적 리소스가 존재하여 네트워크 홉에 의한 지연 시간을 최소한으로 만들어주는 서비스이다. 또한 CF의 Origin 요청/응답 타이밍에 실행되어 S3 접근 직전/직후를 제어하여 동적인 컨텐츠를 생성하는데 유리하다.
ApiGateway, SQS 등 여러 요소들을 사용했으나 이번에는 CF, Edge의 기본 구성과 배포 방식에 대해 정리해놓을려고 한다.
ApiGateway
게이트웨이로 로 요청이 들어오면 람다가 트리거 될 수 있다. 이를 통해 람다의 함수가 실행되어 s3 등에 저장된 파일에 접근, image resize, video encoding 등의 작업을 처리할 수 있다.
CF
사용자는 CF에 요청을 보낸다. CF는 엣지를 트리거하여, 요청과 응답을 재가공한다. 엣지가 S3 Origin으로 요청을 저낟ㄹ하여 파일 또는 이미지를 가져올 수 있다.
CF는 설정 시, 배포 ID가 다음처럼 주어진다.
배포에 들어가서 동작 탭에 들어가면 경로 패턴과 원본 그룹의 매핑 정보를 확인할 수 있다.
각 항목을 클릭하여 편집 버튼을 누르면, 각종 설정 정보를 확인할 수 있고 연결된 엣지 함수도 볼 수 있다.
여기서 유의할 부분은, 엣지 함수의 ARN 주소 값 맨 뒤쪽에 있는 : 뒤 숫자가 버전이라는 것이다. 실제 람다에 들어가서 배포되고 있는 버전 정보를 확인해보고, 여기 CF의 연결 정보에 있는 버전 정보와 일치하는지를 봐야한다. 람다 엣지는 북미(us-east-1)에서만 서비스되므로 리전을 잘 설정하여 조회해야한다. 만약 두 버전 정보가 일치하지 않는다면 버전 정보를 올려서 Save changes 버튼을 눌러 동기화해줘야한다.
동기화는 위 내용처럼 수기로 처리할 수도 있으나, 보통 람다 함수 등을 배포할 때, cdk나 아래 github workflow 예시처럼 엣지 버전 정보가 함께 업데이트 되도록 한다.
CloudFront 설정 및 ETag를 가져오고, 특정 path(/origin/A, ...)로 연결된 LambdaFunctionARN을 업데이트한다. 그리고 변경된 JSON 구성을 cf에 update-distribution 명령어로 CF 배포를 갱신한다.
- name: Update CloudFront Lambda@Edge version Configuration
run: |
# Fetch CloudFront distribution config
config=$(aws cloudfront get-distribution-config --id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }})
etag=$(echo $config | jq -r '.ETag')
distribution_config=$(echo $config | jq '.DistributionConfig')
# Function to update LambdaFunctionARN
update_lambda_function_arn() {
local config=$1
local path_pattern=$2
local function_arn=$3
local function_name=$4
echo $config | jq --arg path_pattern "$path_pattern" --arg function_arn "$function_arn" --arg function_name "$function_name" \
'.CacheBehaviors.Items |= map(
if .PathPattern == $path_pattern then
.LambdaFunctionAssociations.Items |= map(
if (.LambdaFunctionARN | contains($function_name)) then
.LambdaFunctionARN = $function_arn
else
.
end
)
else
.
end
)'
}
# Update S3_COPY and IMAGE_RESIZE configurations
updated_config=$(update_lambda_function_arn "$distribution_config" "/origin/A/*" "$FUNCTION_ARN_s3_copy" "$FUNCTION_NAME_s3_copy")
updated_config=$(update_lambda_function_arn "$updated_config" "/origin/A/*" "$FUNCTION_ARN_s3_copy" "$FUNCTION_NAME_s3_copy")
updated_config=$(update_lambda_function_arn "$updated_config" "/origin/B/*" "$FUNCTION_ARN_image_resize" "$FUNCTION_NAME_image_resize")
updated_config=$(update_lambda_function_arn "$updated_config" "/origin/C/*" "$FUNCTION_ARN_image_resize" "$FUNCTION_NAME_image_resize")
# Update CloudFront distribution
aws cloudfront update-distribution \
--id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} \
--distribution-config "$updated_config" \
--if-match "$etag"