이번 포스팅에서는 AWS 인프라를 활용해서 URL 주소 단축 서비스를 만들어보려 한다.
긴 URL 주소를 단축했을 때의 장점은 아래와 같다
① URL 가독성 개선, 공유 가능
② 사용자 경험 개선 및 클릭률(CTR) 향상
③ 브랜딩과 신뢰도 향상
④ 링크 분석 및 트래킹 가능
⑤ 관리 및 업데이트 용이성
⑥ 제한된 공간에서의 효율성
⑦ URL 관리 용이성
대표적으로 https://bitly.com/와 같은 서비스를 예로 들수 있다. "백문불여일견" 아래를 보면 한 눈에 이해 될 것이다.
AWS 공식 블로그에서는 CloudFront를 앞단에 위치하고 있는데, 이번 포스팅에서는 3단계로 나눠
직접 도메인을 발급하고 Route53 - API Gateway - Lambda - S3 연결하는 과정을 다뤄본다.
Infra Architecture
AWS Toolkit
AWS CLI + VSCode AWS Toolkit Extension 사용하여 로컬에서 쉽게 람다, s3 업로드 할 수 있다
# 패키지 설치
$ sudo apt install unzip -y
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ sudo unzip awscliv2.zip
$ sudo ./aws/install
$ aws --version
VSCode 실행해서 AWS Toolkit Extension 설치해준다
설치가 완료되면 왼쪽 탭 하단에 "aws" 누르면 EXPLORER 통해 현재 profile 기준으로 서비스 목록이 출력된다.
미리 AWS Lambda Function(shorten-url-lambda)을 생성해 두었기 때문에
마우스 우클릭 후 Download를 누르면 아래와 같이 스크립트 파일 내려받아 작업할 수 있게 된다.
간단하게 스크립트 수정 후 업로드를 해보도록 한다.
EXPLORER에서 우클릭 후 Upload Lambda... > Directory > No > 로컬 람다 디렉토리 선택 하면 업로드 된다
AWS 웹 콘솔에서 람다 테스트를 실행(파라미터 추가, {"original_url" : "주소"}), 아래와 같이 정상 실행하는 것을 확인할 수 있다.
S3 버킷 생성
기본 설정에 버킷 이름만 도메인 주소로 지정하여 생성한다.
키 생성 Lambda Function
스크립트 절차는 아래와 같다
① generateRandomKey(..) 사용하여 7자리 key 값을 생성한다 (알파벳 소문자/대문자, 숫자 0-9)
② key 값 중복 확인 후 s3 bucket에 저장한다 (*이때 WebRedirectionLocation에 원본 주소 값을 저장)
③ 정상 실행 완료되면 지정된 응답을 반환한다
import AWS from 'aws-sdk';
import crypto from 'crypto';
const s3 = new AWS.S3({
region : 'ap-northeast-2'
});
const BUCKET_NAME = process.env.S3_BUCKET;
const FORWARD_HOST = process.env.FORWARD_HOST;
const SHORT_KEY_SIZE = parseInt(process.env.SHORT_KEY_SIZE, 10) || 7;
const CHAR_SET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
function generateRandomKey(length) {
let key = '';
const charsetLength = CHAR_SET.length;
for(let i = 1; i <= length; i++) {
const idx = crypto.randomInt(0, charsetLength);
key += CHAR_SET[idx];
}
return key;
}
async function isKeyAvailable(bucket, key) {
try {
await s3.headObject({'Bucket': bucket, 'Key' : key}).promise();
return false;
} catch(error) {
const statusCode = error.statusCode;
if(statusCode === 403 || statusCode === 404) {
return true;
}
throw error;
}
}
async function putObjectOnS3(bucket, key, redirectLocation) {
try {
await s3.putObject({
'Bucket': bucket,
'Key': key,
'Body': '',
'ContentType': 'text/plain',
'WebsiteRedirectLocation': redirectLocation
}).promise();
return true;
} catch(error) {
console.error('Error:', error);
return false;
}
}
export const handler = async (event) => {
const origin = event.native_url;
let id;
let key;
while(true) {
id = generateRandomKey(SHORT_KEY_SIZE);
key = `url/${id}`;
const keyAvailable = await isKeyAvailable(BUCKET_NAME, key);
if(keyAvailable) {
break;
}
}
const isPutSuccess = await putObjectOnS3(BUCKET_NAME, key, origin);
if(!isPutSuccess) {
id = null;
}
return {
'shortId': id,
'forwardUrl': FORWARD_HOST,
'nativeUrl': origin,
}
};
로컬 디렉토리로 이동 후 아래 명령어 실행한 다음 업로드 한다. (node v20.11.0)
$ npm init -y
$ npm install aws-sdk
람다 함수 실행시 S3 Bucket에 대한 읽기와 쓰기 권한이 필요하다. 설정을 위해 권한 탭에 바로가기 링크로 이동한다.
아래와 같이 JSON 형식으로 S3:GetObject, S3:PutObject 권한을 추가한다 (Resource의 경우 S3의 주소를 기재)
람다 함수의 환경 변수 편집에서 스크립트 실행시 필요한 속성과 값들을 추가한다.
람다 함수에서 테스트 실행시 정상적으로 원하는 응답을 반환함을 확인할 수 있었다.
s3 bucket에 해당 key 객체의 메타 데이터 또한 의도한대로 원본 주소가 잘 저장되어 있는 것을 확인했다.
API Gateway 생성
이제 API Gateway Trigger를 생성 및 연결한다. 생성시 REST API 선택 외에는 특별한게 없다.
API 게이트웨이 링크를 클릭하여 이동한다.
메서드 생성 버튼을 눌러서 POST 메서드를 추가한다.
생성한 POST 메서드에 대한 테스트를 실행한다.
요청 본문(body)에 native_url 기재 후 테스트 실행하면 원하는 응답 결과를 확인할 수 있다.
API 배포
default 스테이지 선택 후 배포 버튼을 누르면 endpoint가 생성되고 외부에서 호출 가능하다.
참고. Postman으로 API Gateway endpoint 호출 결과
Reference.
AWS Blog - Build a Serverless, Private URL Shortener
유튜브 - AWS를 통해 서버 없이 단축 URL 서비스 만들기 #1
AWS - Invoking Lambda with events from other AWS services
AWS Document - Using the Lambda context object to retrieve Node.js function information
'공부 > DevOps' 카테고리의 다른 글
[AWS] 서버리스 기반 URL 주소 단축 서비스 구현 - (3) 도메인 연결, S3 정적 웹 호스팅 (1) | 2024.09.24 |
---|---|
[AWS]서버리스 기반 URL 주소 단축 서비스 구현 - (2) 포워딩 람다 구현 (0) | 2024.09.24 |
[AWS] VPC, Subnet, EC2 개발 인프라 구성 (선착순 쿠폰 발급 시스템) (0) | 2024.09.20 |
[NHN Cloud] 컨테이너 기반 Prometheus, Grafana 모니터링 환경 구성(by 오픈 소스 툴) (0) | 2024.09.02 |
[NHN Cloud] 기본적인 웹 서버, DB 인프라 구축 (vpc, subnet, floating ip, ..) (5) | 2024.08.30 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!