Terraform 기본 – Week 6: 첫 번째 Terraform 모듈 구축 및 사용

발행: (2025년 12월 8일 오전 06:41 GMT+9)
8 min read
원문: Dev.to

Source: Dev.to

이전 주 차 요약

지난 5주 동안 우리는 핵심 Terraform 개념을 배우면서 작지만 현실적인 Azure 환경을 구축했습니다. 첫 번째 VM을 배포하는 것으로 시작해 변수와 tfvars 파일을 도입해 구성의 유연성을 높였습니다. NSG와 동적 블록으로 보안을 추가하고, 마지막으로 출력 값을 통해 유용한 정보를 노출했습니다.

현재까지 구축한 인프라의 시각적 표현은 다음과 같습니다:

Infrastructure

Visual Studio Code에서의 폴더 구조:

Folder Structure

프로젝트 폴더의 주요 파일

  • nsg.tf – 네트워크 보안 그룹 및 연결 정의.
  • outputs.tf – 출력 값.
  • providers.tf – AzureRM 제공자 블록.
  • resource-group.tf – 리소스 그룹 정의.
  • terraform.tfvars – 프로젝트 변수 값.
  • variables.tf – 변수 정의.
  • virtual-machine.tf – 가상 머신 및 NIC 리소스.
  • virtual-network.tf – 가상 네트워크 및 서브넷 리소스.

이 시점에서 우리는 완전하게 작동하고, 매개변수화되며, 보안이 적용된 VM 배포를 갖추었습니다. 구성이 커짐에 따라 반복되는 패턴이 눈에 띄게 되고, 유사한 리소스를 다수 관리하기가 어려워집니다. 바로 Terraform 모듈을 도입하기에 적절한 순간입니다.

이전 주 차

시리즈용 GitHub 저장소:

Terraform 모듈이란 무엇이며 왜 사용하나요?

Terraform 모듈은 재사용 가능한 단일 단위로 묶인 리소스들의 집합입니다. 각 배포마다 동일한 VM, NIC, NSG 블록을 다시 작성하는 대신, 모듈 안에 한 번 정의하고 필요할 때마다 해당 모듈을 호출합니다.

메인 Terraform 파일이 들어있는 폴더가 루트 모듈이며, .tf 파일이 들어있는 모든 하위 폴더는 자식 모듈이 되고 독립적으로 실행될 수 없습니다. 루트 모듈은 입력값을 제공하고, 자식 모듈은 출력값을 반환합니다. 이 관계를 통해 코드를 중복 없이 깔끔하게 재사용할 수 있습니다.

실제 환경에서는 모듈이 필수적입니다. 예를 들어, 개발, 스테이징, 프로덕션 환경에 걸쳐 10개의 VM을 관리하는 팀을 생각해 보세요. 모듈이 없으면 각 환경마다 동일한 리소스 블록을 복사해야 합니다. 태그를 업데이트하거나 NSG 규칙을 조정하는 간단한 변경이라도 여러 곳에 반복 적용해야 하므로 드리프트가 발생하고 유지 보수 비용이 증가합니다.

모듈에 로직을 중앙 집중화하면 다음을 달성할 수 있습니다:

  • 환경 간 일관성 유지.
  • 중복 감소.
  • 인프라 유지 보수 및 확장 용이.

모듈 입력값과 출력값 이해하기

모듈 입력값

입력값은 모듈이 리소스를 생성하는 데 필요한 값입니다. 모듈 내부에서 변수로 정의되며, 루트 모듈이 모듈을 호출할 때 실제 값을 전달합니다. VM 모듈의 일반적인 입력값은 다음과 같습니다:

  • 리소스 그룹 이름 및 위치
  • 서브넷 ID
  • VM 크기
  • 관리자 인증 정보
  • NIC 설정
  • 허용 포트

모듈 출력값

출력값은 자식 모듈에서 루트 모듈로 값을 노출합니다. 이를 통해 루트 구성은 모듈 내부 리소스에 직접 접근하지 않고도 해당 정보를 사용할 수 있습니다. VM 모듈의 일반적인 출력값은 다음과 같습니다:

  • VM ID
  • NIC 이름
  • 프라이빗 IP 주소

이러한 출력값은 구성 내 다른 곳에서 참조하거나 배포 후 표시할 수 있습니다.

첫 번째 Terraform 모듈 만들기

Note: 기존 코드를 재사용 가능한 모듈로 리팩터링하는 과정이며, 처음부터 모듈을 만드는 것이 아닙니다. 실제 상황에서 일련의 리소스를 재사용 가능한 컴포넌트로 전환하는 일반적인 시나리오를 반영합니다.

우리는 VM, NIC, NSG 리소스를 modules/vm 폴더로 이동하고, 리소스 그룹, 가상 네트워크, 서브넷은 루트 구성에 그대로 둡니다. 기존 variables.tf, outputs.tf, terraform.tfvars는 루트에 남아 모듈에 값을 계속 제공합니다.

Step 1: 모듈 폴더 구조 만들기

modules/
└── vm/
    ├── main.tf
    ├── variables.tf
    └── outputs.tf

File Structure

Step 2: 모듈의 main.tf 채우기

원본 virtual-machine.tfnsg.tf 파일에서 가상 머신, NIC, NSG 및 NSG 연결에 해당하는 리소스 블록을 복사해 modules/vm/main.tf에 붙여넣습니다.

Main.tf

(이미지는 복사된 리소스 정의를 보여줍니다.)

Step 3: 모듈 변수 정의

modules/vm/variables.tf를 생성하고 모듈이 필요로 하는 모든 입력값(resource_group_name, subnet_id, vm_size 등)을 선언합니다. 변수 이름과 타입은 루트 구성에 있던 것과 동일하게 사용합니다.

Step 4: 모듈 출력값 정의

modules/vm/outputs.tf를 만들어 VM ID, NIC 이름, 프라이빗 IP 주소와 같은 유용한 값을 노출합니다.

Step 5: 루트 구성에서 모듈 호출

루트 폴더에 module 블록을 추가합니다(예: main.tf 혹은 별도 vm-module.tf 파일). 새 모듈을 참조하고 필요한 변수를 전달합니다:

module "vm" {
  source = "./modules/vm"

  resource_group_name = var.resource_group_name
  location            = var.location
  subnet_id           = azurerm_subnet.main.id
  vm_size             = var.vm_size
  admin_username      = var.admin_username
  admin_password      = var.admin_password
  allowed_ports       = var.allowed_ports
}

루트에 기존 outputs.tf에서 이제 모듈의 출력값을 참조할 수 있습니다. 예:

output "vm_private_ip" {
  value = module.vm.private_ip
}

모듈을 도입함으로써 전체 구성은 그대로 동작하면서 재사용성과 유지 보수성이라는 이점을 얻게 됩니다.

Back to Blog

관련 글

더 보기 »

7일 차 – Terraform의 타입 제약

5일 차에 우리는 변수의 작동을 보았습니다. 오늘은 Terraform에서 타입 제약에 대해 더 깊이 파고듭니다. Primitive Types 원시 타입은 기본 빌딩 블록입니다: str...

AWS Terraform 라이프사이클 규칙

소개 인프라스트럭처 코드(IaC)는 업데이트, 교체 및 삭제 시 리소스가 어떻게 동작하는지에 대한 완전한 제어가 있을 때 가장 강력합니다. Terr...

Terraform 데이터 소스 (AWS)

Terraform 데이터 소스란 무엇인가요? 데이터 소스는 Terraform에서 기존 리소스를 읽기 전용으로 조회하는 기능입니다. 새로운 리소스를 생성하는 대신, Terraform은 ...