Devops/Terraform

[테라폼] 테라폼(Terraform) 완전 정복: AWS 인프라를 Terraform으로 완전 자동화하기 (WAF, API Gateway, Elasticache, Redis, EventBridge) - 3

일요일좋아하는사람 2025. 4. 19. 22:13
728x90
반응형

Terraform + aws

들어가며

앞서 1편에서는 VPC, EC2, IAM 등 기본 인프라 구성부터 시작했고, 2편에서는 ALB, Lambda, CloudFront, Route53, ACM을 포함한 웹 서비스 배포 전반을 다뤘습니다.

이번 3편에서는 더 나아가서, 실제 운영 환경에서 중요한 다음 서비스를 Terraform으로 구성하는 법을 소개합니다:

  • WAF (웹 애플리케이션 방화벽)
  • API Gateway (REST/HTTP 엔드포인트)
  • Elasticache (Redis)
  • Step Functions (워크플로우)
  • EventBridge (이벤트 라우팅)

각 서비스마다 실전 예제를 제공하며, Terraform으로 완전 자동화하는 방식을 보여드릴게요.


목차

  1. WAF (Web ACL) 설정
  2. API Gateway REST/HTTP 구성
  3. Elasticache Redis 클러스터 구성
  4. Step Functions 워크플로우 작성
  5. EventBridge 규칙 및 타겟 설정
  6. 통합 보안 및 로그 관리 팁
  7. 마무리 및 추천 구조

1. WAF (Web ACL) 설정

WAF는 웹 애플리케이션에 대한 공격을 방어하는 방화벽입니다. ALB, CloudFront에 붙여서 SQL Injection, XSS 등 위협을 막을 수 있습니다.

WAF Web ACL 생성

resource "aws_wafv2_web_acl" "main" {
  name        = "terraform-waf"
  scope       = "REGIONAL" # CloudFront는 CLOUDFRONT
  description = "Terraform-managed WAF"
  default_action {
    allow {}
  }

  rule {
    name     = "AWS-AWSManagedRulesCommonRuleSet"
    priority = 1

    override_action {
      none {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesCommonRuleSet"
        vendor_name = "AWS"
      }
    }

    visibility_config {
      sampled_requests_enabled = true
      cloudwatch_metrics_enabled = true
      metric_name = "waf-rule"
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name                = "waf"
    sampled_requests_enabled   = true
  }
}

ALB에 WAF 연결

resource "aws_wafv2_web_acl_association" "alb" {
  resource_arn = aws_lb.alb.arn
  web_acl_arn  = aws_wafv2_web_acl.main.arn
}

2. API Gateway REST/HTTP 구성

HTTP API 생성 (API Gateway v2)

resource "aws_apigatewayv2_api" "example" {
  name          = "example-http-api"
  protocol_type = "HTTP"
}

통합 + 경로 설정

resource "aws_apigatewayv2_integration" "lambda" {
  api_id             = aws_apigatewayv2_api.example.id
  integration_type   = "AWS_PROXY"
  integration_uri    = aws_lambda_function.hello.invoke_arn
  integration_method = "POST"
  payload_format_version = "2.0"
}

resource "aws_apigatewayv2_route" "route" {
  api_id    = aws_apigatewayv2_api.example.id
  route_key = "GET /hello"
  target    = "integrations/${aws_apigatewayv2_integration.lambda.id}"
}

배포 및 스테이지

resource "aws_apigatewayv2_stage" "default" {
  api_id      = aws_apigatewayv2_api.example.id
  name        = "$default"
  auto_deploy = true
}

3. Elasticache Redis 클러스터 구성

Subnet Group

resource "aws_elasticache_subnet_group" "redis" {
  name       = "redis-subnet-group"
  subnet_ids = var.private_subnets
}

보안 그룹

resource "aws_security_group" "redis" {
  name   = "redis-sg"
  vpc_id = var.vpc_id

  ingress {
    from_port   = 6379
    to_port     = 6379
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/16"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Redis 클러스터 생성

resource "aws_elasticache_cluster" "redis" {
  cluster_id           = "my-redis"
  engine               = "redis"
  node_type            = "cache.t3.micro"
  num_cache_nodes      = 1
  parameter_group_name = "default.redis6.x"
  port                 = 6379
  subnet_group_name    = aws_elasticache_subnet_group.redis.name
  security_group_ids   = [aws_security_group.redis.id]
}

4. Step Functions 워크플로우 작성

IAM 역할

resource "aws_iam_role" "step_fn" {
  name = "step-functions-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = "sts:AssumeRole",
        Effect = "Allow",
        Principal = {
          Service = "states.amazonaws.com"
        }
      }
    ]
  })
}

State Machine 생성

resource "aws_sfn_state_machine" "example" {
  name     = "example-workflow"
  role_arn = aws_iam_role.step_fn.arn
  definition = jsonencode({
    Comment = "Example Step Function",
    StartAt = "HelloState",
    States = {
      HelloState = {
        Type     = "Pass",
        Result   = "Hello from Terraform!",
        End      = true
      }
    }
  })
}

5. EventBridge 규칙 및 타겟 설정

규칙 생성

resource "aws_cloudwatch_event_rule" "every_hour" {
  name        = "every-hour"
  description = "Trigger Lambda every hour"
  schedule_expression = "rate(1 hour)"
}

타겟 등록

resource "aws_cloudwatch_event_target" "lambda" {
  rule = aws_cloudwatch_event_rule.every_hour.name
  arn  = aws_lambda_function.hello.arn
}

권한 부여

resource "aws_lambda_permission" "allow_eventbridge" {
  statement_id  = "AllowExecutionFromEventBridge"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.hello.function_name
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.every_hour.arn
}

6. 통합 보안 및 로그 관리 팁

  • 모든 서비스에 공통 태그 사용: Environment, Owner, Project
  • WAF + ALB + CloudWatch 조합은 기본
  • API Gateway → Lambda → Step Functions 연결 시 IAM 권한 주의
  • 상태 파일은 항상 S3 + DynamoDB로 관리 (backend 설정)
terraform {
  backend "s3" {
    bucket         = "terraform-state-prod"
    key            = "global/terraform.tfstate"
    region         = "ap-northeast-2"
    dynamodb_table = "terraform-lock"
    encrypt        = true
  }
}

7. 마무리 및 추천 구조

지금까지 세 개의 시리즈 글을 통해 AWS 인프라를 Terraform으로 자동화하는 모든 구성 요소를 살펴보았습니다. 여기까지 따라오셨다면 다음과 같은 구성을 코드로 다룰 수 있을 거예요:

  • 네트워크: VPC, Subnet, NAT, Internet Gateway
  • 컴퓨팅: EC2, Auto Scaling, EKS, ECS
  • 보안: IAM, WAF, SG, ACM, SSM
  • 배포: ALB, Route53, CloudFront, Lambda
  • 백엔드: RDS, ElastiCache, S3
  • 오케스트레이션: Step Functions, EventBridge
728x90
반응형