AWS/인프라 구축 / / 2023. 8. 10. 12:26

CloudWatch 로그 S3로 자동 백업

반응형

AWS Architecture

  • Amazon EventBridge에서 Cron 기반 일정으로 매일 0시에 SNS에 주제를 게시
  • SNS에 주제가 게시되면 구독자인 SQS로 메세지 전달
  • Lambda 함수는 SQS에 도착한 메시지를 트리거로 실행
  • Lambda 함수가 실행되면 S3로 하루치 CloudWatch 로그 전송
  • S3에 저장된 로그는 180일이 경과하면 S3 Glacier로 전환하여 비용 절약

 

1. S3

1-1. S3 생성

버킷 > 권한 > 버킷 정책 편집

CloudWatch에서 로그를 가져올 수 있도록 버킷 권한 설정

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowLogsToWriteToBucket",
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.amazonaws.com"
            },
            "Action": [
                "s3:GetBucketAcl",
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::4team-log-bucket",
                "arn:aws:s3:::4team-log-bucket/*"
            ]
        }
    ]
}

 

 

1-2. S3 LifeCycle 생성

버킷 > 관리 > 수명 주기 규칙 > 수명 주기 규칙 생성

 

180일 경과한 로그는 Glacier Deep Archive로 전환하여 비용 절약

 

 

2. SQS 생성

표준으로 생성

 

3. SNS 주제 생성

3-1. SNS 생성

표준으로 생성

 

 

3-2. SQS를 구독자로 생성

SNS > 주제 > 구독 > 구독 생성

 

4. Lambda

4-1. Lambda 생성

 

4-2. SQS 트리거 추가

 

+ Permission 에러 발생하는 경우

the provided execution role does not have permissions to call receivemessage on sqs 에러가 뜨는 경우 Lambda 권한에 SQS 권한을 추가한다.

(https://bobbyhadz.com/blog/aws-lambda-provided-execution-role-does-not-have-permissions 참고)

 

Lambda > 구성 > 권한

 

4-3. 환경 변수 설정

Lambda > 구성 > 환경변수

 

DESTINATION_BUCKET → 버킷 이름
GROUP_NAME → 로그 그룹 이름
PERIOD → 기간

 

 

4-4. 함수 코드 수정

import boto3
import os
import datetime

GROUP_NAME = os.environ['GROUP_NAME']
DESTINATION_BUCKET = os.environ['DESTINATION_BUCKET']
PREFIX = os.environ['PREFIX']
PERIOD = os.environ['PERIOD']
PERIOD = int(PERIOD)

currentTime = datetime.datetime.now()
startDate = currentTime - datetime.timedelta(PERIOD)
endDate = currentTime - datetime.timedelta(PERIOD - 1)

fromDate = int(startDate.timestamp() * 1000)
toDate = int(endDate.timestamp() * 1000)

BUCKET_PREFIX = os.path.join(PREFIX, startDate.strftime('%Y{0}%m{0}%d').format(os.path.sep))

def lambda_handler(event, context):
    print(currentTime, startDate, endDate, PERIOD, fromDate, toDate)
    client = boto3.client("logs")
    client.create_export_task(
        logGroupName= GROUP_NAME,
        fromTime = fromDate,
        to=toDate,
        destination=DESTINATION_BUCKET,
        destinationPrefix=BUCKET_PREFIX
        )

 

 

 

4-5. 함수 테스트

Deploy 버튼 클릭 후 Test 버튼 클릭

정상 작동 시 아래처럼 결과가 뜬다.

 

 

그리고 S3 버킷을 확인해보면 테스트 결과 확인 가능

 

 

5. EventBridge

 

 

 

매일 정각에 반복적으로 SNS 실행

 

 

결과

이튿날 S3 버킷 확인

 

날짜별 폴더 생성

 

CloudWatch Fluentbit가 수집한 로그 목록

 

(에러)SNS notification failed?

SNS 알림 실패로 로그 자동 저장이 안되는 오류가 발생했었다.

 

아래 링크 참고해서 SQS 엑세스 정책 수정

Subscribing an Amazon SQS queue to an Amazon SNS topic - Amazon Simple Notification Service

 

Subscribing an Amazon SQS queue to an Amazon SNS topic - Amazon Simple Notification Service

When you give another AWS account access to a resource in your account, you are also giving IAM users who have admin-level access (wildcard access) permissions to that resource. All other IAM users in the other account are automatically denied access to yo

docs.aws.amazon.com

 

# 수정 전 엑세스 정책
{
  "Version": "2012-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__owner_statement",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::408223505404:root"
      },
      "Action": "SQS:*",
      "Resource": "arn:aws:sqs:ap-northeast-2:408223505404:log_export_sqs"
    }
  ]
}
# 수정된 엑세스 정책
{
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "sns.amazonaws.com"
      },
      "Action": "sqs:SendMessage",
      "Resource": "arn:aws:sqs:ap-northeast-2:408223505404:log_export_sqs",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:sns:ap-northeast-2:408223505404:log_export_sns"
        }
      }
    }
  ]
}
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유