Overview
알람 자동화 함수에 대상 AWS 서비스를 추가하고 스케쥴러를 설정하겠습니다.
인프라 엔지니어가 내부 원리 및 테라폼과 관계없이 AWS 콘솔에서 태그만 설정하면 자동으로 알람이 설정하도록 구성하였습니다.
1. 람다 함수 트리거 설정
CloudWatchAutoAlarms 은 대상 자원이 생성/삭제되었을 때만 트리거가 호출됩니다. 인스턴스 자원이 이미 생성되어 있는 경우에는 알람 자동화 설정 대상에 제외되며 추가 설정이 필요합니다. 이에 람다 함수 트리거를 설정하여 스케쥴러를 설정하여 람다 함수가 호출되도록 설정하겠습니다.
스케쥴러의 경우 예약 표현식에서 설정이 가능합니다.
# 1분마다 트리거 호출
rate(1 minute)
# 일일마다 트리거 호출
# cron(Minutes Hours Day-of-month Month Day-of-week Year)
cron(0 0 * * ? *)
2. 기존 AWS 서비스 알람 자동화
기존 AWS 서비스에 알람 자동화를 위해 트리거 추가와 람다 함수 수정이 필요합니다.
람다 로그를 확인하면 알람 설정 대상이 트리거를 호출한 AWS 서비스로 설정되어있기 때문입니다.
코드 로직을 확인하면 detail 블록을 통해 알람을 설정하는 것을 확인할 수 있습니다.
이를 전체 AWS 대상으로 수정하기 위해 코드 로직을 다음과 같이 수정하였습니다.
- event 대상이 아닌 전체 EC2 대상
- 반복문을 통한 태그 식별 및 설정 함수 호출
업데이트한 코드를 반영하고 스케쥴러 함수 로그를 확인하면 정상적으로 알람이 설정된 것을 확인할 수 있습니다.
3. 알람 대상 AWS 서비스 추가
알람 자동화 대상이 EC2, Lambda, RDS 셋으로 서비스 대상을 추가하겠습니다.
추가 대상과 알람 설정은 깃허브 오픈소스를 참고하였습니다.
AWS 서비스
|
Metric
|
조건
|
AWS/RDS
|
CPUUtilization
|
GreaterThanThreshold, 5m, 1, Average, Created_by_CloudWatchAutoAlarms, 75
|
|
FreeableMemory
|
LessThanThreshold, 5m, 1, Average, Created_by_CloudWatchAutoAlarms, 75
|
AWS/EC2
|
CPUUtilization
|
GreaterThanThreshold, 5m, 1, Average, Created_by_CloudWatchAutoAlarms, 75
|
AWS/Lambda
|
Errors
|
GreaterThanThreshold, 5m, 1, Average, Created_by_CloudWatchAutoAlarms, 1
|
|
Throttles
|
GreaterThanThreshold, 5m, 1, Average, Created_by_CloudWatchAutoAlarms, 1
|
AWS/ApplicationELB
|
HTTPCode_ELB_5XX_Count
|
GreaterThanThreshold, 5m, 1, Sum, 100
|
|
HTTPCode_Target_5XX_Count
|
GreaterThanThreshold, 5m, 1, Sum, 100
|
|
TargetResponseTime
|
GreaterThanThreshold, 5m, 1, p99, 3
|
|
HealthyHostCount
|
LessThanThreshold, 5m, 1, Minimum, 1
|
AWS/NetworkELB
|
HealthyHostCount
|
LessThanThreshold, 5m, 1, Minimum, 1
|
AWS/ElastiCache
|
CPUUtilization
|
GreaterThanThreshold, 5m, 1, Average, Created_by_CloudWatchAutoAlarms, 75
|
|
DatabaseMemoryUsagePercentage
|
GreaterThanThreshold, 5m, 1, Average, Created_by_CloudWatchAutoAlarms, 75
|
1) 함수 로직 추가
다른 서비스의 알람 추가를 위해 람다 함수를 다음과 같이 수정하였습니다.
- cw_auto_alarms.py : Cloudwatch 메트릭 추가 및 로직 추가
- action.py: 함수 정의로 위 메트릭에 맞게 Cloudwatch 알람을 추가합니다.
2) 변수 추가
변수 임계 값을 변수화하여 알람 조건을 변수에 따라 조절되도록 설정하겠습니다.
3) 이벤트 추가
자원 변동에 따라 이벤트를 추가하기 위해 Cloudwatch 이벤트 규칙을 추가합니다.
이벤트에서 람다함수를 호출하기 위해 Rule 설정, 타겟 설정, 권한 부여가 필요합니다.
resource "aws_cloudwatch_event_rule" "elb_event_rule" {
name = "Initiate-CloudWatchAutoAlarmsELB"
description = "Creates and deletes CloudWatch alarms for ELB instances"
event_pattern = jsonencode({
source = ["aws.elasticloadbalancing"],
detail-type = ["AWS API Call via CloudTrail"],
detail = {
eventSource = ["elasticloadbalancing.amazonaws.com"],
eventName = ["CreateLoadBalancer", "DeleteLoadBalancer"]
}
})
state = var.event_state
}
resource "aws_cloudwatch_event_target" "elb_event_target" {
rule = aws_cloudwatch_event_rule.elb_event_rule.name
target_id = "elbEventTarget"
arn = aws_lambda_function.cloudwatch_auto_alarms.arn
}
resource "aws_lambda_permission" "elb_event_permission" {
statement_id = "AllowExecutionFromCloudWatchEventsELB"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.cloudwatch_auto_alarms.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.elb_event_rule.arn
}
- aws_cloudwatch_event_rule.elb_event_rule: ELB 인스턴스의 생성 및 삭제 이벤트를 처리하기 위한 규칙을 생성합니다.
- aws_cloudwatch_event_target.elb_event_target: ELB 이벤트가 발생하면 Lambda 함수를 호출하도록 설정합니다.
- aws_lambda_permission.elb_event_permission: ELB 이벤트에서 Lambda 함수를 호출할 수 있도록 권한을 부여합니다.
4) 권한 추가
Lambda 함수가 AWS서비스(EC2, ELB, RDS, ElastiCache) 를 조회하기 위해 권한을 추가해야 합니다. 테라폼 모듈 내 iam.tf 에 아래와 같이 조회 권한을 추가했습니다.
# iam.tf
...
{
Effect = "Allow"
Action = ["rds:ListTagsForResource", "rds:DescribeDBInstances"]
Resource = "*"
},
{
Effect = "Allow"
Action = ["ec2:DescribeInstances", "ec2:DescribeImages"]
Resource = "*"
},
{
Effect = "Allow"
Action = ["ec2:CreateTags"]
Resource = "arn:aws:ec2:*:*:instance/*"
},
{
Effect = "Allow"
Action = ["cloudwatch:DescribeAlarms", "cloudwatch:DeleteAlarms", "cloudwatch:PutMetricAlarm"]
Resource = "arn:aws:cloudwatch:*:*:alarm:${var.alarm_identifier_prefix}-*"
},
{
Effect = "Allow"
Action = ["cloudwatch:DescribeAlarms"]
Resource = "*"
},
{
Effect = "Allow"
Action = ["lambda:ListFunctions", "lambda:ListTags"]
Resource = "*"
},
{
Effect = "Allow"
Action = ["elasticache:DescribeCacheClusters", "elasticache:ListTagsForResource"]
Resource = "*"
},
{
Effect = "Allow"
Action = ["elasticloadbalancing:DescribeLoadBalancers", "elasticloadbalancing:DescribeTags"]
Resource = "*"
}
..
모듈 업데이트 후 테스트를 해보겠습니다. 모듈 업데이트는 테라폼 명령어을 통해 진행합니다.
terraform plan
terraform apply
임의의 ELB를 생성하여 알람 설정이 제대로 되는 지 확인하겠습니다.
임의의 ALB를 생성하고, Tag 키에 Create_Auto_Alarms를 추가합니다.
4.1 UCMP 모듈 적용 (에러 사례)
모듈 테스트가 끝났다면 다른 인프라 구성 모듈에 적용하겠습니다.
구성 적용 인프라 모듈은 책, 테라폼으로 시작하는 IaC 마지막 챕터 UCMP 를 참고하였습니다.
# UCMP 모듈 다운로드
git clone https://github.com/terraform101/terraform-refactoring-and-modularity.git
# 브랜치 변경
git checkout -b modularity origin/modularity
# 경로 확인
tree .
.
├── README.md
├── Template_UCSI_1_prd.jpeg
├── main.tf
├── modules
│ ├── common
│ │ ├── README.md
│ │ ├── main.tf
│ │ ├── output.tf
│ │ └── variable.tf
│ └── eks
│ ├── README.md
│ ├── aws-iam-authenticator
│ ├── iam-policy.json
│ ├── kubectl
│ ├── main.tf
│ ├── output.tf
│ ├── template
│ │ ├── cert-manager.tpl
│ │ ├── crd.tpl
│ │ ├── eniconfig.tpl
│ │ ├── ingress.tpl
│ │ ├── kubeconfig.tpl
│ │ └── sa.tpl
│ └── variable.tf
├── output.tf
└── variable.tf
modules 아래에 알람 자동화 모듈(cloudwatch_auto_alarms)을 추가하고 모듈 호출과 변수를 추가합니다.
# main.tf
..
module "cloudwatch_auto_alarms" {
source = "./modules/cloudwatch_auto_alarms"
memory = var.memory
event_state = var.event_state
alarm_notification_arn = var.alarm_notification_arn
alarm_identifier_prefix = var.alarm_identifier_prefix
}
# variable.tf
...
variable "memory" {
description = "Memory to allocate to Lambda function"
type = number
default = 128
}
variable "event_state" {
description = "Create Cloudwatch event to trigger execution on instance start / terminate."
type = string
default = "ENABLED"
}
variable "alarm_notification_arn" {
description = "Enter the Amazon SNS Notification ARN for alarm notifications, leave blank to disable notifications."
type = string
default = ""
}
마지막으로 UCMP 모듈 태그에 Create_Auto_Alarms 를 추가합니다.
# main.tf
..
provider "aws" {
region = var.region
// test
access_key = var.AWS_ACCESS_KEY_ID
secret_key = var.AWS_SECRET_ACCESS_KEY
default_tags { // 모든 resource에 기본으로 설정되는 Tag
tags = {
Environment = var.env
Project = var.pjt
COST_CENTER = "${var.env}_${var.pjt}"
TerraformManaged = true
PrivateInformation = var.private_information
Create_Auto_Alarms = "" # 알람 추가
}
}
}
..
테라폼 클라우드는 본 장에서는 다루지 않는 내용으로 적용 전 내용을 삭제합니다.
terraform {
# cloud {
# organization = "LG-uplus"
# hostname = "app.terraform.io"
# workspaces {
# name = "iac-academy"
# }
# }
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.0.0, < 4.0.0"
}
}
}
인프라 배포시 알람 모듈 내에서 오류가 발생합니다.
aws_cloudwatch_event_rule 사용 모듈 버전이 다르기 때문인데요. UCMP에서 사용하는 모듈 버전은 3.75.2 로 state 라는 변수가 없기에 발생하는 문제입니다.
모듈 문서 내용을 참고하여 state가 is_enable로 되어 있는 것을 확인하고 default 값이 true로 되어있어 삭제를 진행합니다.
그럼에도 불구하고 일부 자원을 생성하지 못합니다.
UCMP 모듈 내 유효하지 않은 값으로 EC2 AMI, EKS를 생성하지 못하는 것을 확인할 수 있습니다.
모듈 자체 내 문제기에 다른 모듈에서 테스트하겠습니다.
4.2 3 tier 모듈 적용
3 티어 모듈을 가져와서 알람 자동화를 테스트하겠습니다.
해당 모듈은 dev/stage/prod 로 환경이 나눠져있기에 prod안에서 S3 버킷과 모듈 추가를 진행해줍시다.
# repo
git clone https://github.com/BJWRD/three-tier-architecture.git
cd three-tier-architecture/envs/prod
# State S3 설정
vi version.tf
..
backend "s3" {
bucket = "" # S3 설정
key = "terraform.tfstate"
region = "ap-northeast-2" # 지역 설정
}
..
# EC2, RDS 모듈 내 태그 추가
vi moudules/ec2.tf
..
locals {
required_tags = {
project = var.project_name,
environment = var.environment,
Create_Auto_Alarms = "" # 추가
}
}
vi modules/rds.tf
..
locals {
required_tags = {
project = var.project_name,
environment = var.environment,
Create_Auto_Alarms = "" # 추가
}
}
해당 모듈도 테라폼 지원 버전 오류로 에러가 발생합니다.
맥 환경 기준 tfenv 를 통해 테라폼 버전을 맞춰줍시다.
# 테라폼 버전 설정
tfenv use 1.3.9
# 모듈 버전 업그레이드
terraform init -upgrade
# 모듈 초기화
terraform init
# 인프라 적용 및 배포
terraform plan
terraform apply
적용이 완료되고 cloudwatch를 확인하면 알람이 자동으로 추가된 것을 확인할 수 있습니다.
'Cloud Tech' 카테고리의 다른 글
EKS에서 Atlantis 구성하기 (0) | 2024.07.14 |
---|---|
EKS Karpenter로 부드럽게 Migration 하기 (2) | 2024.07.06 |
테라폼 모듈을 활용한 CloudWatch Alarm 자동화 (0) | 2024.06.22 |
Terraform 내부 로직 이해 (0) | 2024.06.15 |
SonarQube를 활용한 EKS CleanCode CI /CD 파이프라인 구축하기 (0) | 2024.04.20 |