728x90
반응형
✨ 들어가며
이전 글에서는 Terraform을 이용해 AWS의 기초 인프라 서비스들인 VPC, IAM, EC2, EKS, ECS, Fargate 등을 구성하는 방법에 대해 살펴봤습니다. IAM 사용자 생성, EC2 인스턴스 배포, Kubernetes 클러스터 구축까지 자동화해보며 인프라를 코드로 관리하는 경험을 해보셨을 텐데요.
이번 글에서는 조금 더 확장된 인프라 서비스들인 Route53, ALB, Lambda, CloudWatch, CloudFront 같은 고급 AWS 리소스들을 Terraform으로 어떻게 구성할 수 있는지 구체적인 예제와 함께 소개하려고 합니다.
목차
- Terraform으로 Route53 도메인/레코드 관리
- Application Load Balancer(ALB) 구성
- Lambda 함수 배포
- CloudWatch 로그 및 메트릭 설정
- CloudFront CDN 구성
- 보안그룹, 인증서(ACM), HTTPS 연동
- 정리 및 실전 팁
1. Route53 도메인/레코드 관리
도메인 등록은 Terraform으로 할 수 없어
Terraform은 AWS에서 직접 도메인을 등록하는 기능은 없지만, 이미 등록된 도메인의 호스팅 존과 레코드 관리는 가능합니다.
예시: 호스팅 존과 A 레코드 생성
resource "aws_route53_zone" "main" {
name = "example.com"
}
resource "aws_route53_record" "www" {
zone_id = aws_route53_zone.main.zone_id
name = "www.example.com"
type = "A"
ttl = 300
records = ["203.0.113.10"]
}
ALB와 연동한 레코드 생성
resource "aws_route53_record" "alb_record" {
zone_id = aws_route53_zone.main.zone_id
name = "app.example.com"
type = "A"
alias {
name = aws_lb.alb.dns_name
zone_id = aws_lb.alb.zone_id
evaluate_target_health = true
}
}
2. ALB (Application Load Balancer) 구성
ALB 생성
resource "aws_lb" "alb" {
name = "app-load-balancer"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.lb.id]
subnets = var.subnet_ids
tags = {
Environment = "production"
}
}
리스너와 대상 그룹 구성
resource "aws_lb_target_group" "web" {
name = "web-target-group"
port = 80
protocol = "HTTP"
vpc_id = var.vpc_id
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.alb.arn
port = 80
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.web.arn
}
}
3. Lambda 함수 배포
Terraform은 S3에 zip 파일을 업로드하고 Lambda 함수로 배포할 수 있도록 지원합니다.
예제 코드
resource "aws_iam_role" "lambda_exec" {
name = "lambda_exec_role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}]
})
}
resource "aws_lambda_function" "hello" {
function_name = "helloLambda"
role = aws_iam_role.lambda_exec.arn
handler = "index.handler"
runtime = "nodejs18.x"
filename = "lambda/hello.zip"
source_code_hash = filebase64sha256("lambda/hello.zip")
}
이벤트 트리거 연결 예: API Gateway
resource "aws_apigatewayv2_api" "http_api" {
name = "lambda-http-api"
protocol_type = "HTTP"
}
resource "aws_apigatewayv2_integration" "lambda_integration" {
api_id = aws_apigatewayv2_api.http_api.id
integration_type = "AWS_PROXY"
integration_uri = aws_lambda_function.hello.invoke_arn
integration_method = "POST"
payload_format_version = "2.0"
}
4. CloudWatch 모니터링 설정
Lambda나 EC2, ALB 등의 로그를 수집하려면 CloudWatch 로그 그룹 설정이 필요합니다.
예제: CloudWatch 로그 그룹 생성
resource "aws_cloudwatch_log_group" "lambda_logs" {
name = "/aws/lambda/helloLambda"
retention_in_days = 14
}
CloudWatch 알람 예: CPU 80% 초과 시 경고
resource "aws_cloudwatch_metric_alarm" "cpu_high" {
alarm_name = "high-cpu-alarm"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "120"
statistic = "Average"
threshold = "80"
alarm_description = "이 인스턴스는 CPU 사용률이 80%를 넘었습니다."
dimensions = {
InstanceId = aws_instance.web.id
}
}
5. CloudFront CDN 구성
CloudFront는 전 세계 엣지 위치를 통해 콘텐츠를 빠르게 제공할 수 있는 CDN입니다.
S3 + CloudFront 연결 예제
resource "aws_cloudfront_origin_access_identity" "oai" {
comment = "OAI for S3"
}
resource "aws_s3_bucket_policy" "s3_policy" {
bucket = aws_s3_bucket.example.bucket
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = aws_cloudfront_origin_access_identity.oai.iam_arn
}
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.example.arn}/*"
}
]
})
}
resource "aws_cloudfront_distribution" "cdn" {
origin {
domain_name = aws_s3_bucket.example.bucket_regional_domain_name
origin_id = "s3-origin"
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.oai.cloudfront_access_identity_path
}
}
enabled = true
is_ipv6_enabled = true
default_root_object = "index.html"
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "s3-origin"
viewer_protocol_policy = "redirect-to-https"
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
6. 보안과 HTTPS 구성
ACM (AWS Certificate Manager) 인증서 생성 예
resource "aws_acm_certificate" "cert" {
domain_name = "app.example.com"
validation_method = "DNS"
}
ALB와 HTTPS 연결
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.alb.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = aws_acm_certificate.cert.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.web.arn
}
}
7. 정리 및 실전 팁
Terraform으로 구성할 수 있는 AWS 서비스는 이 외에도 매우 다양합니다:
- Elasticache (Redis/Memcached)
- SNS / SQS
- DynamoDB / Aurora / DocumentDB
- Step Functions / EventBridge
실전 팁
- 상태 파일은 S3 + DynamoDB로 저장하고 잠금 관리하세요.
- terraform workspace를 사용하여 개발/운영 환경을 나눌 수 있습니다.
- CI/CD와 연동할 때는 terraform plan 결과를 PR에 붙이는 것도 좋은 방법입니다.
- 변경 이력 관리를 위해 terraform-docs, tflint, checkov 등의 도구를 함께 쓰세요.
728x90
반응형