100===Dev Ops/Terraform

Terraform: 코드형 인프라(IaC) 완전 정복하기 🏗️

블로글러 2024. 6. 12. 17:21

Terraform 그리고 코드형 인프라(Infrastructure as Code, IaC)를 들어보셨나요? 클라우드 환경이 확산되면서 인프라를 코드로 관리한다는 개념이 점점 중요해지고 있습니다.

일상적인 비유로 생각해보면, Terraform은 마치 건축 설계도와 같습니다.

  • 건물을 지을 때 설계도가 있으면 누가 작업해도 동일한 결과물이 나오듯이, Terraform은 인프라에 대한 '설계도'를 코드로 작성합니다.
  • 레고 블록처럼 필요한 인프라 조각들을 코드로 정의하고 조립할 수 있습니다.
  • 한번 작성한 설계도(코드)는 계속 재사용이 가능하며, 변경 사항을 추적할 수 있습니다.

왜 필요한가?

전통적인 인프라 관리 방식에는 다음과 같은 문제점들이 있습니다:

  1. 수동 구성의 위험성:

    • 클릭과 같은 수동 작업은 휴먼 에러를 발생시킵니다.
    • 복잡한 서버, 네트워크, 보안 설정을 일일이 수동으로 하는 것은 실수하기 쉽습니다.
    • 한 번 잘못 설정된 인프라는 장애와 보안 위험을 초래합니다.
  2. 환경 간 불일치:

    • 개발, 테스트, 운영 환경 간의 구성 차이가 버그와 예상치 못한 동작을 야기합니다.
    • 수동으로 복제된 환경은 미묘한 차이를 가지게 되어 "내 환경에선 잘 되는데요" 현상이 발생합니다.
  3. 변경 관리의 어려움:

    • 인프라 변경 이력을 추적하기 어렵습니다.
    • 인프라 변경이 애플리케이션에 미치는 영향을 예측하기 힘듭니다.
    • 장애 발생 시 이전 상태로 롤백하기 복잡합니다.

기본 원리

Terraform의 핵심 원리를 알아볼까요?

선언적 접근 방식

# AWS 인스턴스 생성 예시
resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  tags = {
    Name = "example-instance"
  }
}

Terraform은 "어떻게(How)" 리소스를 생성할지가 아니라 "무엇을(What)" 원하는지 선언합니다. 즉, 최종 상태를 정의하면 Terraform이 현재 상태와 비교하여 필요한 변경사항을 자동으로 적용합니다.

HCL(HashiCorp Configuration Language)

Terraform은 HCL이라는 자체 설정 언어를 사용합니다:

# 변수 정의
variable "region" {
  description = "The AWS region to deploy resources"
  type        = string
  default     = "ap-northeast-2"
}

# 모듈 사용
module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["${var.region}a", "${var.region}b"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]
}

HCL은 JSON보다 읽기 쉽고 주석을 지원하며, 변수와 함수를 활용할 수 있어 유연하게 인프라를 정의할 수 있습니다.

실행 워크플로우

Terraform의 주요 명령어와 실행 흐름은 다음과 같습니다:

  1. terraform init:

    • 필요한 Provider 플러그인을 다운로드
    • 백엔드 설정 초기화
    • 모듈 다운로드
  2. terraform plan:

    • 현재 상태와 정의된 상태를 비교
    • 적용될 변경 사항 미리보기 제공
    • 발생 가능한 오류 사전 감지
  3. terraform apply:

    • plan에서 확인된 변경 사항 실제 적용
    • 실행 전 최종 확인 제공
    • 변경 결과 및 출력값 표시
  4. terraform destroy:

    • 생성된 모든 리소스 삭제
    • 환경 정리 시 유용

상태 관리

# 원격 상태 저장소 설정
terraform {
  backend "s3" {
    bucket         = "terraform-state-bucket"
    key            = "project/terraform.tfstate"
    region         = "ap-northeast-2"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
}

Terraform은 생성한 리소스의 상태를 terraform.tfstate 파일에 저장합니다. 이 상태 파일은:

  • 현재 인프라 상태에 대한 "진실의 원천(source of truth)"입니다.
  • 팀 협업 시 원격 저장소(S3, Consul 등)에 저장하는 것이 좋습니다.
  • 상태 잠금(state locking)을 통해 동시 수정으로 인한 충돌을 방지합니다.
  • 민감한 정보를 포함할 수 있으므로 보안에 주의해야 합니다.

실제 예제

실제 비즈니스 환경에서 Terraform을 어떻게 활용하는지 살펴보겠습니다.

기본 AWS 인프라 구축

# VPC 설정
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "main-vpc"
    Environment = "production"
  }
}

# 서브넷 설정
resource "aws_subnet" "public" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "public-subnet"
  }
}

# 보안 그룹 설정
resource "aws_security_group" "web" {
  name        = "web-sg"
  description = "Allow web inbound traffic"
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

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

# EC2 인스턴스 생성
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.public.id

  security_groups = [aws_security_group.web.id]

  tags = {
    Name = "web-server"
  }
}

실전 활용

다음은 실제 프로젝트에서 어떻게 활용되는지 보여주는 예시입니다:

상황 일반적인 방법 Terraform 활용 방법 개선효과
개발 환경 복제 수동으로 각 서비스 설정 환경별 변수만 변경하여 동일 코드 재사용 구성 시간 90% 단축, 일관성 100% 보장
멀티 리전 배포 각 리전마다 콘솔에서 반복 작업 리전 변수만 변경하여 동일 인프라 배포 작업 시간 80% 단축, 휴먼 에러 제거
인프라 확장 수동으로 리소스 추가 및 설정 코드 변경 후 자동 적용 확장 시간 70% 단축, 예측 가능한 결과
DR(재해복구) 설정 복잡한 매뉴얼 준비 및 테스트 코드로 DR 환경 자동화 복구 시간 50% 단축, 신뢰성 향상

기업 사례

카카오뱅크는 Terraform을 활용하여 인프라 자동화를 구현했습니다. 이를 통해:

  • 인프라 구성 시간을 크게 단축했습니다.
  • 환경 간 일관성을 확보했습니다.
  • 변경 관리 프로세스를 개선했습니다.

우아한형제들도 Terraform을 도입하여:

  • 인프라 변경에 대한 코드 리뷰 프로세스를 도입했습니다.
  • 인프라 변경 이력을 Git으로 관리합니다.
  • 다양한 환경(개발, 스테이징, 운영)을 일관되게 관리합니다.

주의사항 및 팁 💡

⚠️ 이것만은 주의하세요!

  1. 상태 파일 관리

    • 상태 파일(terraform.tfstate)은 반드시 안전하게 보관하세요.
    • 팀 단위 작업 시 원격 백엔드(S3, GCS 등)를 사용하세요.
    • DynamoDB 등을 활용해 상태 잠금(state locking)을 구현하세요.
  2. 민감한 정보 처리

    • 암호, API 키 등을 코드에 하드코딩하지 마세요.
    • AWS KMS, HashiCorp Vault 등 안전한 비밀 관리 도구를 연동하세요.
    • .tfvars 파일은 .gitignore에 추가하여 민감한 변수를 보호하세요.
  3. 모듈화와 재사용성

    • 모든 코드를 한 파일에 작성하지 마세요.
    • 공통 기능은 모듈로 분리하여 재사용하세요.
    • 모듈은 적절한 입출력 변수와 문서화를 갖추세요.

💡 꿀팁

  • 워크스페이스 활용: 여러 환경(개발, 테스트, 운영)을 관리할 때 workspace 기능을 활용하세요.
  • 명명 규칙 통일: 리소스, 변수, 출력값 등에 일관된 명명 규칙을 적용하세요.
  • 코드 포맷팅: terraform fmt 명령어로 코드 스타일을 일관되게 유지하세요.
  • 코드 검증: terraform validate로 적용 전 코드 오류를 미리 확인하세요.
  • 점진적 적용: 한 번에 모든 인프라를 코드화하려 하지 말고, 점진적으로 도입하세요.

마치며

지금까지 Terraform과 코드형 인프라(IaC)에 대해 알아보았습니다. 처음에는 어렵게 느껴질 수 있지만, 인프라를 코드로 관리하면 얻을 수 있는 이점은 매우 큽니다. 안정성, 일관성, 재현성, 자동화 등 현대 클라우드 환경에서 필수적인 가치를 모두 제공합니다.

혹시 궁금한 점이 있으시거나, 더 알고 싶은 내용이 있으시면 댓글로 남겨주세요. 다음에는 Terraform의 고급 기능과 실제 대규모 프로젝트 적용 사례에 대해 더 자세히 알아보도록 하겠습니다.

참고 자료 🔖


#Terraform #InfrastructureAsCode #DevOps #클라우드자동화 #IaC

728x90
반응형