티스토리 뷰

아래와 같이 Lambda를 통해 Account A의 S3에 저장된 데이터를 그대로 Account B의 S3로 복사하는 과정을 알아보겠습니다. 

 

 

Lambda는 python을 사용하여 작성하였습니다.

import json
import boto3
from urllib.parse import unquote_plus

def lambda_handler(event, context):
    source_client = boto3.client('s3')
    
    destination_client = boto3.client('s3', aws_access_key_id='XXXXX', aws_secret_access_key='XXXXX')
    
    for record in event['Records']:
        bucket = record['s3']['bucket']['name']
        key = unquote_plus(record['s3']['object']['key'])
        
        # 복사할 소스 파일 가져오기
        source_response = source_client.get_object(Bucket=bucket, Key=key)
        
        # 대상 s3에 그대로 내용 복사
        destination_client.upload_fileobj(source_response['Body'], 'DESTINATION_BUCKET_NAME',key)
        
        # 복사한 뒤 소스 S3 내 파일 삭제
        source_client.delete_object(Bucket=bucket, Key=key)

 

작업을 하던 중 아래와 같은 요청 사항이 추가되었습니다.

  • 소스 S3에 폴더(yyyy-MM-dd-HH-mm-ss) 단위로 데이터가 저장
  • 기존 대상 S3에 복사된 데이터를 모두 삭제하고 소스 S3에 마지막에 추가된 폴더만 복사될 수 있도록 처리

 

따라서 아래와 같은 코드를 추가하였습니다.

import json
import boto3
from urllib.parse import unquote_plus

def lambda_handler(event, context):
    source_client = boto3.client('s3')
    
    destination_client = boto3.client('s3', aws_access_key_id='XXXXX', aws_secret_access_key='XXXXX')
    
    for record in event['Records']:
        bucket = record['s3']['bucket']['name']
        key = unquote_plus(record['s3']['object']['key'])
        source_response = source_client.get_object(Bucket=bucket, Key=key)
        
        # 파일 복사 전 이미 복사된 파일 삭제
        delete_bucket(destination_client, 'DESTINATION_BUCKET_NAME', key.split('/')[0])
        
        destination_client.upload_fileobj(source_response['Body'], 'DESTINATION_BUCKET_NAME',key)
    
# 대상 S3 내 기존 데이터 삭제 (대상 s3, 대상 bucket 이름, 디렉토리명) - 같은 디렉토리에 저장된 파일은 삭제하지 않기 위함
def delete_bucket(s3_client, bucket_name, dir_name):
    objects = s3_client.list_objects(Bucket=bucket_name)
    content = objects.get('Contents', [])
    # bucket 내 모든 파일을 하나씩 확인하면서 
    for obj in content:
        key = obj['Key']
        # 상위 디렉토리가 다른 경우에만 파일 삭제
        if dir_name != key.split('/')[0]:
            s3_client.delete_object(Bucket=bucket_name, Key=key)
    # s3_client.delete_bucket(Bucket=bucket_name) # 버킷 자체를 삭제

 

이 방식은 운영 계정의 로그 데이터를 개발 계정으로 복사해서 분석하고 싶은 경우와 같이 여러가지 목적으로 계정간 데이터 공유를 필요로 할 때 사용할 수 있습니다.


* Lambda 함수 생성 후 트리거로 S3를 추가합니다. 원하는 버킷을 선택하고 원하는 이벤트를 지정하여 연결합니다.

   이렇게 트리거를 연결하면 S3에 파일이 추가될 때마다 해당 람다 함수가 호출되어 복사를 진행합니다.

트리거 추가하기
트리거 추가 후

 

* Account A에서 Account B 계정의 S3에 접근하기 위해 람다 내에서 대상 S3 호출 시 아래와 같이 access_key와 secret_access_key를 추가해주었습니다.

 

destination_client = boto3.client('s3', aws_access_key_id='XXXXX', aws_secret_access_key='XXXXX')

 

이 키는 Account B에서 IAM으로 사용자를 생성하고 S3에 접근할 수 있는 권한을 부여한 뒤 발급 받은 액세스 키를 적어주면 됩니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함