프로젝트에서 나온 전체 내용 ( 점검 및 방향성 )
클라우드 워치 & SNS: 알람을 클라우드 워치의 SNS, 람다, 슬랙을 통해 구성.
에러 감지: 람다의 특정 로그를 통해 에러 감지 및 알람 구성.
SNS 관리: 람다 로그를 통해 SNS 관리.
알람 종류:
문자: SNS를 통한 푸시 알림.
전화: 페이저 듀티 및 그라파나를 통한 전화 알람.
장애 상황 알람: EC2 종료 시 알람 발송.
메모리 모니터링: 클라우드 워치 에이전트를 통해 메모리 디테일 관리 및 SNS 알람.
WAF 서비스: API 게이트웨이 앞에 설정 가능, 요청 제한.
ALB 액세스 로그: 모바일/웹에서 접근 확인 가능, WAF와 연동 가능.
프로메테우스: 알람 관리.
알람 우선순위: 로그 기반 알람과 EC2 종료 알람.
시연 영상: 알람 시연 준비.
참고 자료: Terraform State 공유 설정 참고 링크: https://github.com/Fastcampus-Kubernetes-Devops/Part_3/tree/main/3-1_Terraform .
버킷을 이용하여 terraform state 공유
iam 권한 추가
CloudWatch Logs에 대한 권한을 추가하기 위해, IAM 역할에 CloudWatch Logs 관련 정책을 추가해야 합니다. 이를 위해 IAM 모듈의 main.tf 파일을 수정하여 필요한 권한을 추가
iam/main.tf
resource "aws_iam_role" "lambda_dynamodb_role" {
name = var.lambda_role_name
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}
]
})
}
resource "aws_iam_policy_attachment" "dynamodb_policy_attachment" {
name = "lambda-dynamodb-policy-attachment"
roles = [aws_iam_role.lambda_dynamodb_role.name]
policy_arn = "arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess"
}
resource "aws_iam_role" "apigateway_cloudwatch_role" {
name = var.api_gateway_role_name
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "apigateway.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
}
resource "aws_iam_policy_attachment" "apigateway_cloudwatch_policy_attachment" {
name = "apigateway-cloudwatch-policy-attachment"
roles = [aws_iam_role.apigateway_cloudwatch_role.name]
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"
}
resource "aws_iam_policy" "cloudwatch_logs_policy" {
name = "cloudwatch-logs-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutMetricFilter",
"logs:DeleteMetricFilter",
"logs:PutRetentionPolicy",
"logs:DeleteRetentionPolicy",
"logs:TagLogGroup"
]
Effect = "Allow"
Resource = "*"
}
]
})
}
resource "aws_iam_policy_attachment" "lambda_cloudwatch_logs_policy_attachment" {
name = "lambda-cloudwatch-logs-policy-attachment"
roles = [aws_iam_role.lambda_dynamodb_role.name]
policy_arn = aws_iam_policy.cloudwatch_logs_policy.arn
}
output "lambda_dynamodb_role_arn" {
value = aws_iam_role.lambda_dynamodb_role.arn
}
iam/variables.tf
variable "lambda_role_name" {
description = "The name of the IAM role for Lambda"
type = string
}
variable "api_gateway_role_name" {
description = "The name of the IAM role for API Gateway"
type = string
}
lambda 함수에 에러가 발생했을 때와 정상적으로 수행되었을 때 모두 로그를 남기도록 수정
import json
import boto3
from botocore.exceptions import ClientError
# DynamoDB 클라이언트 생성
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('dynamodb-html')
def lambda_handler(event, context):
try:
# API Gateway로부터 전달된 요청 바디를 파싱
survey = json.loads(event['body'])
# DynamoDB에 저장할 항목 생성
item = {
'SurveyId': survey['title'].replace(' ', '-').lower(), # Title을 이용하여 SurveyId 생성
'Title': survey['title'],
'Description': survey['description'],
'Questions': survey['questions']
}
# DynamoDB 테이블에 항목 추가
table.put_item(Item=item)
# 성공 로그 생성
print('Survey data saved successfully:', item)
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Origin': '*', # 모든 도메인에서의 요청을 허용
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
'body': json.dumps({'message': 'Survey data saved successfully!'})
}
except ClientError as e:
# 에러 로그 생성
print('Error processing survey:', e.response['Error']['Message'])
return {
'statusCode': 500,
'headers': {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
'body': json.dumps({'message': 'Failed to process survey due to ClientError.'})
}
except Exception as e:
# 에러 로그 생성
print('Error processing survey:', str(e))
return {
'statusCode': 500,
'headers': {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
'body': json.dumps({'message': 'Failed to process survey due to an unexpected error.'})
}
설명
성공 로그:
에러 로그:
ClientError가 발생했을 때 print('Error processing survey:', e.response['Error']['Message'])을 통해 에러 로그를 생성합니다.
일반적인 예외가 발생했을 때 print('Error processing survey:', str(e))을 통해 에러 로그를 생성합니다.
AWS Management Console에 로그인합니다.
CloudWatch 서비스를 엽니다.
왼쪽 메뉴에서 Logs를 선택합니다.
Lambda 서비스를 엽니다.
감지하고자 하는 람다 함수를 선택합니다.
람다 함수의 코드를 업데이트하여 로그를 남기도록 합니다. 이미 제공된 코드에서는 print 문을 통해 로그를 남기고 있습니다.
CloudWatch 서비스로 돌아가서 Logs > Log groups로 이동합니다.
이전에 생성한 로그 그룹을 선택합니다.
Create Metric Filter를 클릭합니다.
필터 패턴에 Error processing survey와 같이 에러 로그 메시지를 식별할 수 있는 패턴을 입력합니다.
Next를 클릭하고 필터 이름과 메트릭 세부 정보를 입력한 후 Create Filter를 클릭합니다.
메트릭 필터 생성 시 세부 정보 입력
예제 입력값
아래는 메트릭 필터 생성 시 예제 입력값입니다.
CloudWatch 서비스에서 Alarms를 선택합니다.
Create Alarm을 클릭합니다.
Select metric을 클릭하고 이전에 생성한 Metric Filter를 선택합니다.
알람 조건을 설정합니다.
Next를 클릭하여 알람 액션을 설정합니다. 여기서 SNS 주제를 선택하거나 새로운 SNS 주제를 생성합니다.
알람 이름을 설정하고 Create Alarm을 클릭합니다.
설정 예제
예를 들어, 다음과 같이 설정할 수 있습니다:
최종 설정 요약
SNS 서비스를 엽니다.
Topics를 선택하고 Create topic을 클릭합니다.
유형을 표준으로 선택합니다.
주제 이름을 입력하고 Create topic을 클릭합니다.
생성된 주제를 선택하고 Create subscription을 클릭합니다.
Protocol을 선택하고 (예: Email, SMS) Endpoint를 입력한 후 Create subscription을 클릭합니다.
예제 설정
SNS 주제 생성
Type: Standard
Name: LambdaErrorNotifications
구독 추가
Protocol: Email
Endpoint: your-email@example.com
구독 확인

