테라폼의 리소스와 모듈의 사용법을 알아보자.
리소스(Resource)는 실제 클라우드 상의 하나의 개별 자원을 정의한다.
AWS EC2, S3, RDS, VPC 같은 것들을 하나씩 직접 생성하는 단위로 생각하면 된다.
resource "aws_instance" "web_server" {
ami = "ami-0abcd1234" # OS 식별자
instance_type = "t3.micro"
}
5개의 인스턴스를 만들어야 한다면 5개의 리소스 코드를 만들어야 한다.
모듈(Module)은 여러 리소스를 묶어놓은 재사용 가능한 패키지다.
하나의 모듈 안에는 리소스들 + 입력 변수 + 출력 값이 함께 정의되어 있어, 여러 프로젝트에서 쉽게 재활용할 수 있다.
"리소스는 클래스(class) 정의고, 모듈은 그 클래스를 활용해 객체(object)를 만드는 것과 같다."
/envs/prod/main.tf # 모듈을 호출하는 곳
/modules/ec2/ # 모듈 정의 디렉터리
├── main.tf # 리소스 정의
├── variables.tf # 입력 변수 정의
└── outputs.tf # 출력 값 정의
# /envs/prod/main.tf ================================
module "ec2_server" {
source = "../../modules/ec2"
instance_name = "${var.vpc_name}-service"
instance_id = var.os_image_id
instance_type = var.service_instance_type
subnet_id = module.private_subnet_c.subnet_id
security_group_ids = [module.ec2_security_group.security_group_id]
}
# /modules/ec2/main.tf ==============================
resource "aws_instance" "instance" {
ami = var.instance_id
instance_type = var.instance_type
subnet_id = var.subnet_id
vpc_security_group_ids = var.security_group_ids
tags = {
Name = var.instance_name
}
}
# /modules/ec2/variables.tf =========================
variable "instance_name" {
description = "EC2 instance name"
type = string
}
variable "instance_type" {
description = "EC2 instance type"
type = string
}
variable "subnet_id" {
description = "Subnet ID"
type = string
}
variable "security_group_ids" {
description = "Security group IDs"
type = list(string)
}
variable "instance_id" {
description = "EC2 AMI ID"
type = string
}
# /modules/ec2/outputs.tf ===========================
output "instance_id" {
description = "생성된 EC2 인스턴스의 ID"
value = aws_instance.instance.id
}
output "instance_arn" {
description = "생성된 EC2 인스턴스의 ARN"
value = aws_instance.instance.arn
}
→ modules/ec2/ 폴더에 미리 정의된 리소스 묶음을 호출해서 사용하는 것
(※ 일반적으로 main.tf, variables.tf, outputs.tf로 구성)
| 파일 | 역할 |
|---|---|
| main.tf | 리소스와 필요한 속성 정의 |
| variables.tf | 리소스 생성에 필요한 입력값을 변수화(모듈 정의에서는 실제 값이 들어가지 않음) |
| outputs.tf | 리소스 생성 결과를 외부로 출력(실제 인스턴스의 식별자 등)/td> |
# 모듈 호출만으로 인프라 확장 가능.
module "server_a" { source = "../../modules/ec2" instance_name = "server-a" ... }
module "server_b" { source = "../../modules/ec2" instance_name = "server-b" ... }
module "server_c" { source = "../../modules/ec2" instance_name = "server-c" ... }
...
1개의 EC2 리소스로 서로 다른 변수값을 가진 5개의 EC2 인스턴스 모듈을 생성할 수 있다.
| 구분 | 리소스 (resource) | 모듈 (module) |
|---|---|---|
| 목적 | 개별 리소스 생성 | 리소스 묶음 재사용 |
| 관리 규모 | 소규모 환경 | 대규모, 표준화 환경 |
| 중복 방지 | 어렵다 | 쉽다 (DRY: Don't Repeat Yourself) |
| 코드 위치 | main.tf 안에 작성 | 별도 디렉터리 분리 |
| 재사용성 | 낮음 | 높음 |
Terraform 공식 레지스트리(https://registry.terraform.io)에
AWS, Azure, GCP용으로 잘 만들어진 공개 모듈들이 이미 준비되어 있다.
module "vpc" {
source = "terraform-aws-modules/vpc/aws" # 관리형 모듈 호출
version = "5.13.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-2a", "ap-northeast-2c"]
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.3.0/24", "10.0.4.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
}
→ 몇 줄 만으로 VPC, 서브넷, IGW, NATGW, 라우팅 테이블까지 모두 구성.
| 항목 | 장점 |
|---|---|
| 개발 속도 | 직접 작성 없이 바로 사용 가능, 빠른 구축 |
| 검증 | 수천 수만 명이 사용하는 검증된 코드 |
| 옵션 다양성 | 다양한 입력 변수를 제공, 유연한 설정 가능 |
| 유지보수 | 모듈 버전만 업데이트하면 최신 기능 적용 |
| 품질 표준화 | 일관성 있는 리소스 생성, 오류 감소 |
| 구분 | 직접 만든 모듈 | 관리형 모듈 사용 |
|---|---|---|
| 사용 목적 | 특수한 커스텀 필요 시 | 표준 구성, 빠른 구축 |
| 관리 비용 | 직접 유지보수 필요 | 버전 업데이트만 관리 |
| 배포 속도 | 느림 (작성 필요) | 빠름 (바로 사용) |
| 추천 상황 | 회사 내부 표준화 필요 시 | 빠른 개발, 소규모/POC 프로젝트 |
Terraform은 리소스를 통해 개별 자원을 생성할 수 있지만, 규모가 커지거나 반복적인 작업이 많아지면 모듈화를 통해 코드 품질과 재사용성을 높이는 것이 중요하다.
직접 모듈을 만들 수도 있지만, Terraform Registry에서 제공하는 검증된 관리형 모듈을 활용하면 개발 속도와 안정성을 동시에 확보할 수 있다.