🔧 DevOps

Terraform

HashiCorp Terraform

IaC 도구. HCL로 인프라 정의. 멀티 클라우드 지원. 선언적 방식으로 리소스 관리.

상세 설명

Terraform은 2014년 HashiCorp가 출시한 Infrastructure as Code(IaC) 도구로, 선언적 구성 언어인 HCL(HashiCorp Configuration Language)을 사용해 클라우드 인프라를 정의하고 관리합니다. 2024년 OpenTofu 포크 이전까지 IaC 분야의 사실상 표준이었습니다.

핵심 개념으로 Provider(AWS, Azure, GCP 등 플랫폼 플러그인), Resource(관리 대상 인프라), State(현재 인프라 상태 저장), Module(재사용 가능한 구성 단위)이 있습니다. terraform plan으로 변경 사항을 미리 확인하고, terraform apply로 실제 적용합니다.

Terraform의 강점은 멀티 클라우드 지원입니다. 3000개 이상의 Provider가 있어 AWS, Azure, GCP는 물론 Kubernetes, Datadog, GitHub 등 다양한 서비스를 하나의 도구로 관리합니다. 상태 파일(tfstate)로 인프라의 현재 상태를 추적하고, 변경 계획을 정확히 예측합니다.

실무에서는 Terraform Cloud/Enterprise로 팀 협업과 상태 파일 관리를 하거나, S3+DynamoDB로 백엔드를 구성합니다. Module을 사용해 VPC, EKS 클러스터 같은 복잡한 구성을 재사용하고, Terragrunt로 DRY(Don't Repeat Yourself) 원칙을 적용합니다.

코드 예제

# main.tf - AWS EKS 클러스터 구성 예제
terraform {
  required_version = ">= 1.5.0"

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

  # 상태 파일 원격 저장
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/eks/terraform.tfstate"
    region         = "ap-northeast-2"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = {
      Environment = var.environment
      ManagedBy   = "Terraform"
    }
  }
}

# variables.tf
variable "aws_region" {
  description = "AWS 리전"
  type        = string
  default     = "ap-northeast-2"
}

variable "environment" {
  description = "환경 (dev, staging, prod)"
  type        = string
}

variable "cluster_name" {
  description = "EKS 클러스터 이름"
  type        = string
}

# EKS 모듈 사용
module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 19.0"

  cluster_name    = var.cluster_name
  cluster_version = "1.28"

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

  eks_managed_node_groups = {
    general = {
      desired_size = 2
      min_size     = 1
      max_size     = 5

      instance_types = ["t3.medium"]
      capacity_type  = "ON_DEMAND"
    }

    spot = {
      desired_size = 2
      min_size     = 0
      max_size     = 10

      instance_types = ["t3.large", "t3.xlarge"]
      capacity_type  = "SPOT"
    }
  }
}

# outputs.tf
output "cluster_endpoint" {
  description = "EKS 클러스터 엔드포인트"
  value       = module.eks.cluster_endpoint
}

output "cluster_name" {
  description = "EKS 클러스터 이름"
  value       = module.eks.cluster_name
}

# 실행 명령어
# terraform init          # 초기화
# terraform plan          # 변경 계획 확인
# terraform apply         # 적용
# terraform destroy       # 삭제

실무에서 이렇게 말해요

시니어: "새 환경 구축에 매번 3일 걸렸는데, Terraform 모듈화하고 나니까 terraform apply 한 번이면 2시간 내로 끝나요."

주니어: "상태 파일은 어디에 저장하나요? 로컬에 두면 협업이 안 될 것 같은데요."

시니어: "S3 백엔드 쓰고 DynamoDB로 락 걸어요. terraform plan은 PR에서 GitHub Actions로 자동 실행되게 해놨어요."

면접관: "Terraform 상태 파일 관리는 어떻게 하셨나요?"

지원자: "S3 버전 관리가 활성화된 버킷에 저장하고, DynamoDB로 state locking을 구현했습니다. Terraform Cloud의 Remote State도 사용해봤는데, 팀 규모가 작을 땐 S3 방식이 비용 면에서 유리했습니다. state 파일 손상 시 복구를 위해 S3 버전 관리는 필수입니다."

리뷰어: "리소스에 depends_on 없이 참조만 하면 암시적 의존성으로 순서가 보장돼요. 명시적으로 넣으면 오히려 유지보수가 힘들어져요."

개발자: "아, module.eks.cluster_endpoint 참조하면 자동으로 EKS가 먼저 생성되는 거군요. depends_on 제거하겠습니다."

주의사항

더 배우기