Cloudwatch의 로그들을 일별로 S3에 백업해두려고 하는데 매일 콘솔로 직접 백업하기는 번거로우니 Lambda를 이용해서 자동화 하려고 한다.
💡 아래 사항이 준비되어 있어야 한다.
1. Cloudwatch 로그 리전과 일치하는 리전의 S3버킷이 있어야 한다.
2. S3와 Cloudwatch logs에 대한 전체 엑세스 권한을 가진 IAM 사용자가 있어야 한다.
1. 권한 설정
S3에 cloudwatch의 로그 데이터를 추출하기 위해서는, S3에서 데이터 입력을 허용하는 설정이 되어 있어야 한다.
데이터를 백업할 S3 버킷에 접속하여 버킷정책을 설정해 준다.
버킷 정책에 아래 권한 정책을 입력한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:GetBucketAcl",
"Effect": "Allow",
"Resource": "arn:aws:s3:::<bucket-name>",
"Principal": { "Service": "logs.<region>.amazonaws.com" }
},
{
"Action": "s3:PutObject" ,
"Effect": "Allow",
"Resource": "arn:aws:s3:::<bucket-name>/*",
"Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } },
"Principal": { "Service": "logs.<region>.amazonaws.com" }
}
]
}
S3 버킷의 권한 설정이 완료 되었으면, Lambda의 실행 Role을 설정해 주어 Cloudwatch와 S3에 접근권한을 준다.
IAM 콘솔에서 새로운 Lambda 실행 Role을 생성하는데, 아래 사진의 AWS 정책 목록을 추가하여 생성해주면 된다.
2. Lambda 함수 작성
위에서 생성한 실행 Role을 사용하도록하여 새로운 Lambda함수를 생성한다.
이제 Lambda 함수의 코드를 작성한다.
아래는 boto3를 사용하여 Cloudwatch의 어제일자의 로그를 S3에 Export 해주는 코드이다.
import os
import datetime
import time
import boto3
from botocore.exceptions import ClientError
'''
get environment Variables
여기서는 Lambda configuration에서 환경변수로 지정해 주었지만,
바로 문자열 변수로 코드에서 지정해도 된다.
'''
bucket = os.environ['S3_BUCKET']
'''
set start ~ end time of log data
추출해올 로그 데이터의 시간을 설정한다.
여기서는 전일자의 로그데이터를 추출한다.(어제 00:00시 ~ 오늘00:00시)
'''
currentTime = datetime.datetime.now()
yesterday = currentTime.date() - datetime.timedelta(days=1)
startTime = datetime.datetime.combine(yesterday,datetime.time(0,0,0))
endTime = datetime.datetime.combine(currentTime.date(), datetime.time(0,0,0))
# convert datetime to int(millisecond)
fromDate = int(startTime.timestamp()*1000)
toDate = int(endTime.timestamp()*1000)
'''
use boto3.client('logs') for cloudwatch
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/logs.html
'''
def lambda_handler(event, context):
# eventbridge로 부터 log group 전달 받음, 버킷명과 마찬가지로 코드에 하드코딩 해도 됨!
parameter = event['Parameters']
logGroup = parameter['logGroup']
'''
set S3 subfolders' structure
S3에 저장될 경로 지정, 여기서는 아래 경로로 저장됨
S3://<BUCKET NAME>/<LOG GROUP>/<YEAR>/<MONTH>/<DAY>/
'''
prefix = os.path.join(logGroup, startTime.strftime('%Y{0}%m{0}%d').format(os.path.sep))
client = boto3.client('logs')
try:
response = client.create_export_task(
logGroupName=logGroup,
fromTime=fromDate,
to=toDate,
destination=bucket,
destinationPrefix=prefix
)
print("Task created: %s" % response['taskId'])
except ClientError as error:
raise error
기본적으로 Lambda 함수는 실행 시간을 3초로 제한하는데, 이 제한 시간을 늘려준다.
람다의 비용은 전송시간에 영향을 받기 때문에 이점을 고려하여 적정 시간을 설정한다.
3. Lambda trigger 스케쥴 설정 (AWS Eventbridge 이용)
Lambda를 매일 일정한 시간에 실행시키기 위해서 Eventbridge의 rules를 이용한다.
Eventbridge 콘솔에서 Rule 생성을 시작하고, 스케쥴 패턴을 설정한다.
나는 매일 오전 12:05분(한국시간)에 실행되도록 설정했다.
rule이 실행시킬 타깃으로 2에서 생성한 Lambda 함수를 지정한다.
참고:
https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/logs/S3ExportTasksConsole.html
https://omardulaimi.medium.com/export-cloudwatch-logs-to-s3-with-lambda-dd45cf246766
'Amazon AWS > S3' 카테고리의 다른 글
Amazon S3 스토리지 클래스 정리 (0) | 2023.05.21 |
---|---|
S3의 불필요한 객체들을 정리하도록 Lambda 작성 (0) | 2023.03.13 |
Presigned Url을 이용하여 외부에서 S3에 접근 (0) | 2022.12.18 |
AWS Athena를 사용해서 S3의 데이터에 쿼리 쓰기 (0) | 2022.11.20 |