개발을 할 때 중복되는 코드를 함수나 클래스로 빼내는 것처럼, Terraform에서도 반복적으로 생성되는 인프라 패턴을 재사용 가능한 블록으로 묶어낼 수 있습니다. 이것이 바로 Terraform 모듈(Module)입니다
모듈의 정의
한 폴더 안에 모여 있는 .tf 파일들의 집합이 바로 모듈입니다. 사실 우리가 작성하는 모든 Terraform 코드는 Root Module(최상위 모듈)입니다. 다른 폴더에서 작성한 코드는 Child Module(하위 모듈)로서 가져다 쓸 수 있습니다
flowchart TD
subgraph env_prod [Root Module: Production]
MAIN_PROD["main.tf"]
end
subgraph env_dev [Root Module: Dev]
MAIN_DEV["main.tf"]
end
subgraph modules [Child Modules]
MOD_VPC["VPC Module"]
MOD_EKS["EKS Module"]
MOD_RDS["RDS Module"]
end
MAIN_PROD -->|"호출<br/>source = ./modules/vpc"| MOD_VPC
MAIN_PROD -->|"호출"| MOD_EKS
MAIN_PROD -->|"호출"| MOD_RDS
MAIN_DEV -->|"호출"| MOD_VPC
MAIN_DEV -->|"호출"| MOD_EKS
classDef primary fill:#2563eb,stroke:#1e40af,color:#ffffff
classDef success fill:#059669,stroke:#047857,color:#ffffff
classDef neutral fill:#475569,stroke:#334155,color:#ffffff
class MAIN_PROD,MAIN_DEV primary
class MOD_VPC,MOD_EKS,MOD_RDS success
class env_prod,env_dev,modules neutral
이렇게 모듈을 분리하면, 개발 환경과 운영 환경이 정확히 동일한 구조(모듈)를 사용하되 Input 값(인스턴스 크기, 서브넷 등)만 다르게 유지할 수 있습니다
Input과 Output 설계
Child Module은 하나의 ‘블랙박스 함수’처럼 동작해야 합니다
| 요소 | 일반 프로그래밍 | Terraform Module |
|---|---|---|
| 입력값 | 함수 파라미터 (Parameters) | variable |
| 반환값 | 리턴값 (Return) | output |
| 지역 변수 | 스코프 내 변수 (Local vars) | locals |
예시: VPC 모듈을 호출하는 Root Module
module "my_vpc" {
source = "./modules/vpc" # 모듈의 위치
vpc_name = "prod-vpc" # Input (Variables)
cidr = "10.0.0.0/16"
}
# 모듈이 만들어낸 결과물을 다른 리소스에서 참조
resource "aws_instance" "web" {
subnet_id = module.my_vpc.private_subnet_id # Output 사용
# ...
}
모듈 작성 원칙
품질 좋은 모듈을 만들기 위해 실무에서 지켜야 하는 원칙들입니다
1. 적절한 파편화 유지
단순히 aws_instance 하나를 감싸기 위해 모듈을 만드는 것은 의미가 없습니다(오히려 변수 매핑 오버헤드만 생깁니다). 반대로 전체 인프라를 하나의 거대 모듈에 다 담으면 모듈의 존재 이유가 사라집니다
“의미 있는 아키텍처 패턴 단위”(예: VPC 네트워크 일체, EKS 클러스터 + 워커노드 그룹, S3 정적 호스팅 설정)로 묶어야 합니다
2. 하드코딩 피하기
모듈 내부에 ap-northeast-2 같은 리전 정보나, 특정 프로젝트의 태그 이름이 박혀 있으면 재사용이 불가능해집니다. 변경될 가능성이 조금이라도 있는 값은 모두 variable로 열어두어야 합니다
3. Public vs Private 모듈
모듈의 소스(source)는 로컬 폴더뿐만 아니라 원격 저장소도 지원합니다
- Public Module: Terraform Registry에 오픈 소스로 등록된 검증된 모듈 (
source = "terraform-aws-modules/vpc/aws") - Private Module: 사내 Git 저장소 등을 통해 팀 내부 규칙이 가득 들어간 모듈 (
source = "git::https://github.com/company/terraform-modules.git//vpc?ref=v1.2.0")
안정적인 인프라 운영을 위해서는 원격 모듈을 호출할 때 항상 버전 태그(ref=v1.2.0)를 고정해야 합니다. 메인 브랜치를 직접 바라보면 모듈 작성자가 코드를 수정할 때 갑자기 인프라가 깨질 위험이 있습니다
정리
- 모듈은 반복 가능한 인프라 아키텍처를 패키징하는 수단입니다
variable로 값을 주입받고,output으로 결과를 내뱉는 블랙박스 구조로 설계하십시오- 원격 저장소를 이용해 사내 표준화를 이룰 수 있으며, 버전 관리는 필수적입니다
모듈화를 통해 HCL 코드를 깔끔하게 정리했습니다. 하지만 여전히 중대한 문제가 하나 남았습니다. 팀원 두 명이 동시에 동일한 인프라를 수정한다면 무슨 일이 벌어질까요? 다음 글에서는 협업을 가능하게 하는 State 파일 원격 관리와 Locking에 대해 알아보겠습니다