AWS 를 활용하다 보면, MSA (Micro Service Architecture) 형식의 시스템 구성을 통해, 비용적인 큰 장점을 가질 수 있습니다. EC2 를 띄우면, 사용하지 않더라도 비용을 지불해야 하지만, Lambda 와 같은 program 만 올려서, 필요할 때만 가동시키면, 사용한 횟수와 각 가동시간의 합으로 비용이 책정됩니다.
저번에 AWS CLI 를 통해, Multipart Upload 를 해 봤는데, 대용량 파일을 잘게 쪼개서 올리다 보니, MD5 Checksum 을 자동으로 실행해 주는 구조를 만들고 싶어 졌습니다.
* AWS | S3 Multipart Upload 사용해 보기
우선 Lambda 를 이용하여 가볍게 운용할 수 있도록 하고 싶었으며, 최대한 AWS native (자체 지원하는) 기능으로 만들고 싶어 졌습니다. Lambda 가 처리할 수 있는 file 용량의 한계가 있어, EFS 등도 연동해야 하지만, 기본적인 골격을 만들어 확인해 보고 싶었기 때문에, 다음과 같은 구성으로 확인해 봤습니다.
S3 File Upload > S3 to Lambda Notify > Lambda Get Object > Logging
위의 Architecture 를 구성하는 방법을 하나씩 구현해 보겠습니다.
1. Lambda - Create
가장 기본이 되는 Lambda function 을 만들어 줍니다. 기본 소스를 짜주는 것도 있지만, arm64 를 활용하고 싶어 제로 베이스로 만들어 봅니다. 나중에 안 사실이지만, Python 버전이나 CPU architecture 는 나중에 바꿀 수 있습니다.
보안을 위한 실행 권한과 S3 접근 권한은, AWS 가 제공하는 기본 권한을 설정 합니다. Lambda 실행 권한은 Role 을 이용하여 설정하고, S3 접근은 Policy 를 이용 하도록 하였습니다. 커서를 해당 설정 칸에 올리고 S3 라고 입력하면 관련 내용들을 선택할 수 있도록, Pull-Down 으로 표시해 줍니다.
Role 이름을 정하고, Amazon S3 object read-only permission 을 선택하였습니다.
2. S3 Bucket - Create
이제, 위에서 만든 Lambda 와 연동할 S3 bucket 을 만들어 줍니다. General purpose 로 만들었습니다.
3. S3 Bucket - Event notifications
S3 Bucket 생성 후, 생성된 bucket 의 설정을 보면, Event notifications 라는 항목이 있습니다. 여기에서, file 이 업로드 된 후, 알림을 보내줄 대상을 설정할 수 있습니다.
Event 이름을 정하고 (저는 Lambda 이름과 동일하게 작성), 어떤 event 에서 알람이 가게 할지를 설정 하였습니다. 일단, file 이 생성되는 그 어느 event 를 모두 포함하는 설정을 해 주었습니다.
알림을 전달할 대상에 대하여, 이번에 새로 만든 Lambda function 을 지정 하였습니다.
4. Lambda - Code
처음에는 Lambda 와 S3 를 연동하기 위해, Lambda function 의 껍데기만 만들었는데, 이제 실제로 동작하는 코드를 올려 봅니다. 참고한 코드는 AWS 에서 제공하는 아래 링크의 소스를 거의 그대로 사용 하였습니다.
* Invoke a Lambda function from an Amazon S3 trigger
기본 소스는 다음과 같으며, 파일명도 표시해 줄 수 있도록 key 도 표시하게 추가 수정 하였습니다.
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
import json
import urllib.parse
import boto3
print('Loading function')
s3 = boto3.client('s3')
def lambda_handler(event, context):
#print("Received event: " + json.dumps(event, indent=2))
# Get the object from the event and show its content type
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
try:
response = s3.get_object(Bucket=bucket, Key=key)
print("FINE NAME: " + key)
print("CONTENT TYPE: " + response['ContentType'])
return {
key,
response['ContentType']
}
except Exception as e:
print(e)
print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
raise e
수정된 source code 를 적용하기 위해, Depoly 를 눌러 줍니다.
5. Lambda - Trigger
이제, S3 와 Lambda 를 서로 연결시켜 주었고, Lambda 가 동작하기 위한 trigger 를 설정 합니다.
Notification 이 오는 S3 bucket 을 대상으로 하고, Event type 에서 "All object create events" 를 선택 하였습니다. 그리고 prefix / suffix 는 모든 대상으로 하기 때문에 특별히 설정하지 않았습니다. 특정 path 나 파일 확장자에 대해서만 실행하고 싶으면, 여기서 추가 설정하면 됩니다.
6. Lambda - Role / Policy
이제, 관련 설정의 마지막인 권한 설정 입니다. AWS 에서는 이 권한 설정이 매우 빡빡하게 되어 있습니다. 그만큼 보안을 중요하게 생각하는 Infra. 입니다. 권한 설정에서는 처음에 만들었던 Role 에서 추가하면 되므로, 아래 메뉴에서 Role name 을 클릭하여 해당 IAM Role 페이지에서 설정하게 합니다.
Lambda function > Configurations > Permissions > Execution role
IAM Roles 로 가서, create inline policy 를 선택 합니다.
Select a serivce 에서 S3 를 타이핑 하면, 선택할 수 있는 대상들을 보여 줍니다. S3 를 선택하면, 해당 bucket 을 선택할 수 있고, S3 Object Lambda 를 선택하면, 어떤 region 인지와 S3 access point (bucket) 을 선택할 수 있게 됩니다. S3 Object Lambda 가 선택하는 범위가 넓습니다. 기본 S3 을 이용해도 되나, Lambda 에서 설정하는 것이라, 저는 S3 Object Lambda 를 선택 했습니다.
GetObject 권한만 필요하므로, 해당 권한만 선택.
Specify ARNs 에서, 해당 accunt 냐, region 이 어디냐, access point 는 어디냐 라고 해서, 사용할 S3 Bucket 이 있는 region 과 Bucket name 을 입력 하였습니다. S3 Object Lambda 가 아니라, 단순 S3 를 앞에서 설정 했으면, Bucket ARN (Bucket name) 만을 입력하게끔 됩니다. 이를 통해 S3 Object Lambda 가 다른 account 와 region 까지 커버할 수 있다는 것을 알 수 있습니다.
Policy 이름을 정하고 마무리 하면 됩니다. 저는 Lambda 이름 뒤에 Policy 만 붙여, 통일성 있는 이름으로 정하였습니다. 나중에 필요 없어지면 삭제도 편합니다. 삭제까지 생각한다면, 동일한 Tag 를 달아 놔도 되겠네요.
S3 접근 Permission 설정 완료.
7. Test / CloudWatch Logs
이제 남은건 확인 입니다. S3 bucket 으로 가서 파일을 하나 올려 봅니다.
Lambda function 의 Monitor 로 와서 확인합니다.
새로운 CloudWatch Logs > Log Stream 이 만들어 졌네요.
Lambda code 에서 설정한 것처럼, key (file name) 과 Centent Type 이 로그에 찍히는 것을 확인할 수 있습니다. Python 코드에 대한 지식이 아직 많지 않아, 이정도 밖에 못 하지만, 조금 경험해 보면서 다양한 정보를 표시할 수 있도록, 특히 JSON 방식으로 표시할 수 있도록 나중에 소스 수정을 해 보겠습니다.
8. Lambda - Settings
맨 처음 이야기 했지만, 실행되는 Lambda function 에 대하여, 실행 완료 시간과 CPU architecture 그리고, 실행에 이용할 Python 버전 등을 설정할 수 있습니다.
활용 가능한 메모리와 storage 도 설정할 수 있습니다. 특히, storage 는 10 GiB 까지 가능하므로, 애초에 목표한 MD5 Checksum 파일이 10GiB 가 넘는 경우는 확인이 불가능 합니다. 그래서 나중에는 EFS (Elastic File Service) 과 연동하는 소스로 수정해 보겠습니다.
네, runtime 환경 설정과, 실행할 CPU architecture 도 변경이 가능 합니다.
오랜만에 코드와 실제 설정을 해보니 즐거웠습니다. 다양한 방법으로 설정할 수 있는 자유도가 있는 AWS 서비스 이지만, detail 하지 못 하면, 하나를 완성할 수 없는, 쉽지 않은 서비스가 AWS 입니다. Open source 를 상업화 한 것이 AWS 라고 생각하면 쉽게 이해할 수 있지요. 점점 여러가지를 활용해 보도록 하겠습니다.
FIN
댓글
댓글 쓰기