본문 바로가기
IT/Cloud

[Cloud] Terraform AWS EKS 모듈 활용: 프로덕션 클러스터 배포 및 관리 가이드

by 수누다 2026. 5. 12.

안녕하세요, 13년차 서버 인프라 엔지니어입니다. 오늘은 Terraform AWS EKS 모듈을 활용해서 프로덕션 환경에 바로 적용할 수 있는 쿠버네티스(Kubernetes) 클러스터를 배포하고 관리하는 방법을 나눠볼게요. 사실 저도 쿠버네티스를 처음 접했을 땐 '이걸 어떻게 프로덕션에 안정적으로 올리지?' 고민이 정말 많았거든요. 수많은 설정과 의존성 때문에 삽질을 꽤 했었습니다. ㅎㅎ

그런데 Terraform(테라폼)과 AWS EKS 모듈을 써보니까, 정말 복잡했던 배포 과정이 깔끔하게 정리되더라고요. 마치 복잡한 미로에서 벗어나는 기분이었죠. 오늘은 제가 직접 경험했던 노하우를 바탕으로, Terraform EKS 모듈이 왜 프로덕션 환경에 필수적인지, 그리고 어떻게 활용하는지 자세히 알려드릴게요.

Terraform으로 관리되는 AWS EKS 클러스터의 일반적인 아키텍처입니다.

개념 정리: 왜 Terraform과 EKS 모듈이 필요할까요?

본격적인 실전으로 들어가기 전에, 핵심 개념들을 간단히 짚고 넘어갈게요. 이미 잘 알고 계신 분들도 있겠지만, 혹시 모르니까 멘토처럼 쉽게 설명해드릴게요.

  • IaC (Infrastructure as Code, 코드형 인프라스트럭처): 인프라를 코드로 관리한다는 뜻이에요. 예전에는 서버 한 대 놓으려면 직접 전산실 가서 설치하고 케이블 연결하고 그랬잖아요? 요즘은 그런 모든 과정을 코드로 정의하고 자동화합니다. Terraform이 바로 이 IaC를 구현하는 대표적인 도구거든요. 코드로 인프라를 관리하면 반복 가능하고, 버전 관리도 되고, 무엇보다 휴먼 에러가 확 줄어든다는 게 최고의 장점입니다. 제가 직접 써보니 정말 그렇더라고요!
  • AWS EKS (Amazon Elastic Kubernetes Service): AWS에서 제공하는 관리형 쿠버네티스 서비스예요. 쿠버네티스는 컨테이너화된 워크로드를 배포하고 관리하는 오픈소스 시스템인데, EKS는 이 쿠버네티스 컨트롤 플레인(Control Plane)을 AWS가 대신 관리해준다는 뜻입니다. 덕분에 우리는 마스터 노드 관리 부담 없이 워커 노드(Worker Node)에만 집중할 수 있죠. 프로덕션 환경에선 안정성이 생명인데, AWS가 관리해주니 정말 마음이 든든합니다.
  • Terraform AWS EKS 모듈: Terraform 오픈소스 커뮤니티가 만들어 놓은 '모듈(Module)'이 있습니다. 이 EKS 모듈은 AWS EKS 클러스터를 배포하는 데 필요한 모든 리소스(VPC, 서브넷, IAM 역할, EKS 클러스터 자체, 노드 그룹 등)를 미리 정의해둔 템플릿 모음이에요. 이걸 사용하면 수백 줄이 넘을 수 있는 Terraform 코드를 몇 줄로 줄일 수 있거든요. 처음엔 직접 다 만들었었는데, 이 모듈을 발견하고 나서는 '아, 이래서 다들 모듈을 쓰는구나!' 하고 무릎을 탁 쳤습니다. 생산성 향상에 정말 최고예요. 🚀

실전 구현: Terraform으로 EKS 클러스터 배포하기

이제 실제로 Terraform AWS EKS 모듈을 사용해서 프로덕션용 EKS 클러스터를 배포해볼게요. 단계별로 차근차근 따라오면 됩니다. 제가 홈랩에서 여러 번 테스트해보고 가장 안정적인 방법을 알려드릴게요.

1. 프로젝트 구조 및 초기 설정

먼저 다음과 같은 디렉토리 구조를 만들어주세요.

mydir/
├── main.tf
├── variables.tf
└── outputs.tf

main.tf 파일에 AWS Provider(프로바이더)를 설정하고, Terraform EKS 모듈을 정의합니다.

# main.tf

terraform {
  required_version = ">= 1.0.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.0"

  name = "${var.cluster_name}-vpc"
  cidr = "10.0.0.0/16"

  azs             = data.aws_availability_zones.available.names
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = true
  single_nat_gateway = true

  tags = {
    "kubernetes.io/cluster/${var.cluster_name}" = "owned"
    "kubernetes.io/role/internal-elb"           = "1"
    "kubernetes.io/role/elb"                    = "1"
  }
}

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.0" # Terraform Registry에서 최신 안정 버전을 확인하세요!

  cluster_name    = var.cluster_name
  cluster_version = var.cluster_version

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  # EKS 클러스터 로깅 활성화 (프로덕션 필수!)
  cluster_enabled_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]

  # 관리형 노드 그룹 (Managed Node Groups)
  managed_node_groups = {
    general = {
      name            = "general-nodes"
      instance_types  = ["t3.medium"]
      min_size        = 2
      max_size        = 5
      desired_size    = 3
      disk_size       = 50
      labels          = { env = "production", role = "general" }
      capacity_type   = "ON_DEMAND"
      # EKS 노드에 SSH 접속이 필요하다면 아래 주석 해제 후 키 페어 이름 설정
      # key_name = "your-ssh-key-name"
    }
    # 추가 노드 그룹이 필요하면 여기에 정의
    # spot = {
    #   name          = "spot-nodes"
    #   instance_types  = ["t3.small", "t3.medium"]
    #   min_size        = 0
    #   max_size        = 10
    #   desired_size    = 1
    #   capacity_type   = "SPOT"
    #   disk_size       = 20
    # }
  }

  tags = {
    Project     = "EKS-Production"
    Environment = "Prod"
  }
}

data "aws_availability_zones" "available" {}

⚠️ 주의사항: t3.medium은 테스트용으로 괜찮지만, 실제 프로덕션 워크로드에는 더 큰 인스턴스 타입(예: m5.large, c5.large)을 고려하세요. 그리고 version = "~> 20.0" 부분은 항상 Terraform Registry에서 최신 안정 버전을 확인해서 사용하세요. Terraform AWS EKS 모듈이 워낙 빠르게 업데이트돼서 제가 작성한 시점과 다를 수 있거든요.

variables.tf 파일에는 클러스터 이름, AWS 리전, EKS 버전 등 변경될 수 있는 값들을 정의합니다.

# variables.tf

variable "aws_region" {
  description = "AWS region."
  type        = string
  default     = "ap-northeast-2" # 서울 리전
}

variable "cluster_name" {
  description = "Name of the EKS cluster."
  type        = string
  default     = "my-prod-eks-cluster"
}

variable "cluster_version" {
  description = "Kubernetes version."
  type        = string
  default     = "1.28" # 사용 가능한 EKS 버전 확인 후 지정
}

outputs.tf 파일에는 배포 후 필요한 정보를 출력하도록 설정합니다. 클러스터 엔드포인트나 kubeconfig 명령어 같은 것들이죠.

# outputs.tf

output "cluster_endpoint" {
  description = "Endpoint for EKS Control Plane."
  value       = module.eks.cluster_endpoint
}

output "kubeconfig_command" {
  description = "Command to configure kubectl."
  value       = "aws eks update-kubeconfig --region ${var.aws_region} --name ${var.cluster_name}"
}

output "cluster_security_group_id" {
  description = "Security group ID of the EKS cluster."
  value       = module.eks.cluster_security_group_id
}

Terraform EKS 모듈을 위한 주요 구성 파일들의 역할과 관계를 보여줍니다.

2. Terraform 명령 실행

파일들을 모두 작성했다면, 터미널을 열고 해당 디렉토리로 이동해서 다음 명령어를 실행합니다.

  1. Terraform 초기화 (Initialize): 필요한 프로바이더와 모듈을 다운로드합니다.
  2. terraform init
  3. Terraform 실행 계획 (Plan): 실제로 어떤 리소스들이 생성/변경/삭제될지 미리 보여줍니다. 이 단계에서 항상 꼼꼼히 확인하는 습관을 들이셔야 해요. 저는 여기서 실수 몇 번 해보고 크게 깨달았습니다. 😅
  4. terraform plan
  5. Terraform 적용 (Apply): 계획대로 리소스를 AWS에 배포합니다. 시간이 좀 걸릴 수 있어요. 커피 한 잔 마시면서 기다려보세요. 😊--auto-approve 옵션은 실제 프로덕션 환경에서는 신중하게 사용해야 합니다. 보통은 terraform apply만 실행해서 직접 승인하는 과정을 거치는 게 안전하거든요.
  6. terraform apply --auto-approve

⚠️ 주의사항: 삽질 경험과 해결책

제가 13년간 인프라 엔지니어로 일하면서 느낀 건, 아무리 잘 만들어진 도구라도 '삽질'은 피할 수 없다는 거예요. Terraform EKS 모듈도 마찬가지입니다. 몇 가지 흔한 문제와 제가 겪었던 해결책을 공유해드릴게요.

  • VPC Subnet Tag 누락: EKS 클러스터가 서브넷을 제대로 인식하지 못해서 배포가 실패하는 경우가 종종 있어요. 특히 다른 모듈로 VPC를 만들었거나 수동으로 서브넷을 구성했을 때 그렇더라고요. EKS는 워커 노드를 프로비저닝할 때 특정 태그(kubernetes.io/cluster/YOUR_CLUSTER_NAMEkubernetes.io/role/internal-elb 또는 kubernetes.io/role/elb)가 있는 서브넷을 찾습니다. main.tf의 VPC 모듈 설정에서 태그를 꼭 넣어주세요.
  • tags = { "kubernetes.io/cluster/${var.cluster_name}" = "owned" "kubernetes.io/role/internal-elb" = "1" "kubernetes.io/role/elb" = "1" }
  • IAM 권한 부족: Terraform을 실행하는 IAM 사용자 또는 역할에 EKS, EC2, IAM, VPC 관련 권한이 충분히 부여되지 않으면 문제가 생길 수 있습니다. 특히 EKS Administrator와 유사한 관리자 권한을 가진 정책을 사용하거나, 필요한 최소 권한을 직접 설정해야 하죠. 저는 처음에 너무 최소 권한만 주려다가 여러 번 권한 에러를 만났습니다. 그럴 땐 일단 잠시 넓은 권한을 줘서 문제가 권한 때문인지 확인하고, 잘 되면 다시 최소 권한으로 조이는 방법을 썼어요.
  • 모듈 버전 충돌 또는 비호환성: Terraform AWS EKS 모듈은 빠르게 업데이트됩니다. 특정 Terraform 버전, AWS Provider 버전, EKS 클러스터 버전과의 호환성을 항상 확인해야 해요. Terraform Registry에서 해당 모듈의 Required ProvidersRequirements 섹션을 꼭 확인하세요. 버전이 맞지 않으면 예상치 못한 에러가 발생할 수 있거든요.
  • 노드 그룹의 인스턴스 타입/AMI 문제: EKS 워커 노드가 정상적으로 클러스터에 조인되지 않는 경우가 있습니다. 주로 EKS 버전과 호환되지 않는 AMI(Amazon Machine Image)를 사용했거나, 인스턴스 타입이 해당 리전에서 지원되지 않을 때 발생합니다. Terraform EKS 모듈은 기본적으로 EKS 최적화 AMI를 사용하지만, 사용자 지정 AMI를 사용할 경우 주의해야 합니다.

검증 및 결과: 클러스터 확인하기

Terraform apply가 성공적으로 완료되었다면, 이제 EKS 클러스터가 잘 배포되었는지 확인해볼 차례예요. 🎉

1. Kubeconfig 설정

먼저 outputs.tf에서 출력된 kubeconfig_command를 실행해서 kubectl이 EKS 클러스터에 접속할 수 있도록 설정합니다. 이 명령어를 실행하면 ~/.kube/config 파일이 업데이트될 겁니다.

aws eks update-kubeconfig --region ap-northeast-2 --name my-prod-eks-cluster

2. 노드 확인

이제 kubectl 명령어로 클러스터 노드들을 확인해봅시다. 워커 노드들이 Ready 상태로 잘 올라와 있어야 합니다.

kubectl get nodes
NAME                                           STATUS   ROLES    AGE     VERSION
ip-10-0-1-123.ap-northeast-2.compute.internal   Ready    <none>   5m20s   v1.28.x
ip-10-0-2-234.ap-northeast-2.compute.internal   Ready    <none>   5m15s   v1.28.x
ip-10-0-3-345.ap-northeast-2.compute.internal   Ready    <none>   5m10s   v1.28.x

3. AWS Console에서 확인

AWS Management Console(관리 콘솔)에 로그인해서 EKS 서비스로 이동하면, 방금 배포한 클러스터가 목록에 보일 거예요. 클러스터 이름을 클릭해서 상세 정보를 확인하고, 노드 그룹 탭에서 워커 노드들이 정상적으로 실행 중인지도 확인해볼 수 있습니다.

AWS EKS 콘솔에서 배포된 클러스터와 노드 그룹의 상태를 확인하는 모습입니다.

마무리, 그리고 다음 단계

오늘은 Terraform AWS EKS 모듈을 활용해서 프로덕션 레디(Production-Ready) 쿠버네티스 클러스터를 배포하고 관리하는 방법을 자세히 알아봤습니다. 제가 직접 겪은 삽질 경험과 해결책도 함께 공유해드렸는데, 도움이 되셨으면 좋겠네요.

Terraform EKS 모듈 덕분에 우리는 복잡한 EKS 인프라를 빠르고 안정적으로 구축할 수 있게 됐어요. IaC의 강력함을 다시 한번 느낄 수 있었던 경험이었죠. 처음엔 진입 장벽이 좀 있다고 느낄 수 있지만, 한번 익숙해지면 이만큼 편리한 게 없습니다. 정말 강력한 도구거든요.

Terraform AWS EKS 모듈을 사용했을 때 얻을 수 있는 주요 이점들을 시각적으로 요약했습니다.

다음 단계로는 이렇게 배포된 EKS 클러스터에 Ingress Controller(인그레스 컨트롤러, 외부 트래픽을 클러스터 내부 서비스로 라우팅), Cert-Manager(인증서 관리), Prometheus(프로메테우스, 모니터링 시스템) 같은 필수 애드온(Add-on)들을 Terraform으로 함께 배포하는 방법을 다뤄볼 예정이에요. 그리고 CI/CD 파이프라인(Continuous Integration/Continuous Deployment Pipeline, 지속적 통합/배포 파이프라인)과 연동해서 인프라 변경을 자동화하는 방법도 흥미로운 주제가 될 것 같습니다.

궁금한 점이나 추가적인 삽질 경험이 있으시다면 댓글로 자유롭게 남겨주세요! 함께 고민하고 해결해나가는 게 인프라 엔지니어의 묘미 아니겠습니까? 😊