목차
- IaC 도구 선택, 왜 이렇게 어렵냐고요 😅
- Terraform과 Pulumi, 각각 어떤 도구인가요?
- Terraform — IaC의 베테랑
- Pulumi — 개발자 친화적인 도전자
- Pulumi vs Terraform 핵심 차이점 비교
- 실전에서 느끼는 차이 — 직접 써보니까요
- Terraform이 빛나는 순간들
- Terraform의 아픈 부분 😅
- Pulumi가 빛나는 순간들
- Pulumi의 아픈 부분 ⚠️
- ⚠️ 실전에서 주의해야 할 것들
- Terraform 상태 파일(State File) 관리
- Pulumi 스택(Stack) 분리 전략
- Terraform 라이선스 변경 이후 고민
- 결국 뭘 선택해야 할까요? — 상황별 가이드
- ✅ Terraform을 선택하면 좋은 경우
- ✅ Pulumi를 선택하면 좋은 경우
- 자주 묻는 질문 (FAQ)
- Q. Terraform에서 Pulumi로 마이그레이션할 수 있나요?
- Q. 둘 다 멀티 클라우드(Multi-Cloud)를 지원하나요?
- Q. Pulumi는 무료인가요?
- Q. 둘 다 Kubernetes(쿠버네티스) 관리에 적합한가요?
- 마무리 — 결국 중요한 건 팀과 컨텍스트
IaC 도구 선택, 왜 이렇게 어렵냐고요 😅
팀에서 인프라 자동화 도구를 새로 도입하려고 할 때, 가장 먼저 나오는 질문이 있죠. "Terraform 쓸까요, Pulumi 쓸까요?"
저도 몇 년 전에 이 선택 앞에서 한참 고민했거든요. 당시엔 Terraform이 거의 IaC(Infrastructure as Code, 코드로 인프라를 정의하고 관리하는 방식)의 표준처럼 여겨지던 시절이었는데, Pulumi라는 새로운 녀석이 등장하면서 "이거 써야 하나?" 싶었던 기억이 납니다.
결론부터 말씀드리면 — 둘 다 써봤고, 둘 다 장단점이 뚜렷해요. Pulumi vs Terraform 비교는 단순히 "어느 게 더 좋냐"의 문제가 아니라, 팀 상황과 프로젝트 성격에 따라 달라지는 문제더라고요. 오늘은 13년 동안 인프라 엔지니어로 일하면서 직접 겪은 경험을 바탕으로, 이 두 IaC 도구를 제대로 비교해드리겠습니다.
Pulumi와 Terraform의 전체적인 구조와 접근 방식 차이를 보여주는 개요 다이어그램
Terraform과 Pulumi, 각각 어떤 도구인가요?
Terraform — IaC의 베테랑
Terraform은 HashiCorp에서 만든 오픈소스 IaC 도구로, 2014년에 처음 출시됐습니다. HCL(HashiCorp Configuration Language)이라는 자체 DSL(Domain-Specific Language, 특정 목적을 위해 만들어진 언어)을 사용하는 게 특징이에요.
쉽게 말해서, "인프라를 선언적으로 정의"하는 방식입니다. "EC2 인스턴스 이렇게 만들어줘"라고 적어두면, Terraform이 알아서 현재 상태와 비교해서 필요한 작업만 수행하는 거죠.
# Terraform 예시 — AWS EC2 인스턴스 생성
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "web-server"
Environment = "production"
}
}
output "instance_ip" {
value = aws_instance.web_server.public_ip
}
처음 보면 "이게 뭔 언어야?" 싶을 수 있는데, 몇 번 써보면 꽤 직관적이더라고요. 특히 인프라 구성을 "읽는" 관점에서는 진짜 편합니다.
Pulumi — 개발자 친화적인 도전자
Pulumi는 2018년에 등장한 비교적 젊은 IaC 도구입니다. 가장 큰 차별점은 실제 프로그래밍 언어를 그대로 사용한다는 점이에요. Python, TypeScript, Go, C#, Java 등을 지원하거든요.
처음 이걸 봤을 때 "오, 이거 개발자들 좋아하겠다" 싶었어요. 인프라 엔지니어보다 소프트웨어 개발자 출신이 많은 팀이라면 특히요.
# Pulumi 예시 — Python으로 AWS EC2 인스턴스 생성
import pulumi
import pulumi_aws as aws
web_server = aws.ec2.Instance(
"web-server",
ami="ami-0c55b159cbfafe1f0",
instance_type="t3.micro",
tags={
"Name": "web-server",
"Environment": "production",
}
)
pulumi.export("instance_ip", web_server.public_ip)
같은 결과물인데, Python 개발자라면 아래 코드가 훨씬 익숙하게 느껴질 겁니다. 이게 Pulumi의 핵심 가치예요.
Pulumi vs Terraform 핵심 차이점 비교
자, 이제 본격적으로 비교해 봅시다. 제가 직접 두 도구를 써보면서 느낀 차이점들을 정리했어요.
| 비교 항목 | Terraform | Pulumi |
|---|---|---|
| 언어 | HCL (자체 DSL) | Python, TypeScript, Go, C# 등 |
| 학습 곡선 | HCL은 쉽지만, 복잡한 로직은 어려움 | 언어는 익숙하지만 Pulumi 개념 학습 필요 |
| 상태 관리 | 로컬 파일 또는 원격 백엔드 | Pulumi Cloud 또는 자체 백엔드 |
| 프로바이더 생태계 | 매우 방대 (성숙한 생태계) | 성장 중 (Terraform 프로바이더 브리지 지원) |
| 테스트 | 제한적 (Terratest 등 별도 도구 필요) | 언어 기본 테스트 프레임워크 활용 가능 |
| 커뮤니티 | 매우 활발, 레퍼런스 풍부 | 성장 중 |
| 라이선스 | BSL 1.1 (v1.5.5부터 변경) | Apache 2.0 (오픈소스) |
| 엔터프라이즈 기능 | Terraform Cloud/Enterprise | Pulumi Cloud |
⚠️ 라이선스 변경 이슈 주의! Terraform은 2023년 8월에 라이선스를 MPL 2.0에서 BSL(Business Source License) 1.1로 변경했습니다. 이 때문에 OpenTofu라는 포크 프로젝트가 생겼을 정도로 커뮤니티에서 논란이 됐었어요. 상업적 목적으로 사용할 때는 라이선스 조건을 꼭 확인하세요.
Terraform의 plan/apply 워크플로우와 Pulumi의 preview/up 워크플로우를 나란히 비교한 다이어그램
실전에서 느끼는 차이 — 직접 써보니까요
Terraform이 빛나는 순간들
제가 Terraform을 처음 도입했을 때가 2019년쯤이었는데, 당시 팀에 인프라 엔지니어가 저 포함 3명이었어요. 개발팀과 협업할 일이 많았는데, HCL 파일을 코드 리뷰할 때 개발자들도 꽤 잘 읽더라고요. 선언적 문법이라 "이 리소스가 이렇게 생겼구나"를 직관적으로 파악하기 좋거든요.
특히 이런 상황에서 Terraform이 강점을 발휘했어요:
- 💡 팀에 인프라 전문가 비율이 높을 때 — HCL에 익숙해지면 오히려 더 깔끔하게 관리됨
- 💡 레퍼런스가 중요할 때 — 거의 모든 클라우드 리소스에 대한 예제가 넘쳐남
- 💡 안정성이 최우선일 때 — 10년 넘은 도구라 예측 가능한 동작이 보장됨
- 💡 모듈 재사용이 핵심일 때 — Terraform Registry의 공개 모듈 생태계가 압도적
# Terraform 모듈 활용 예시
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-2a", "ap-northeast-2b", "ap-northeast-2c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
tags = {
Environment = "production"
Terraform = "true"
}
}
Terraform Registry에서 검증된 VPC 모듈 몇 줄로 완성이에요. 이런 거 보면 "역시 생태계가 갑이다" 싶죠.
Terraform의 아픈 부분 😅
근데 솔직히 말씀드리면, 복잡한 로직 처리할 때는 좀 힘들어요. 예를 들어 "조건에 따라 리소스 개수를 동적으로 결정"하려면...
# Terraform에서 동적 리소스 생성 — 이게 직관적이지 않음
resource "aws_security_group_rule" "ingress_rules" {
count = length(var.ingress_ports)
type = "ingress"
from_port = var.ingress_ports[count.index]
to_port = var.ingress_ports[count.index]
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.main.id
}
# for_each를 쓰면 좀 낫지만, 여전히 복잡한 로직엔 한계가 있음
resource "aws_instance" "servers" {
for_each = var.server_configs
ami = each.value.ami
instance_type = each.value.instance_type
tags = {
Name = each.key
}
}
count, for_each 같은 메타 인수를 쓰다 보면 "이게 프로그래밍이 아니라 퍼즐 푸는 느낌"이 들 때가 있어요. 저도 처음엔 이게 뭔가 싶었는데, 익숙해지는 데 시간이 좀 걸렸습니다 ㅎㅎ
Pulumi가 빛나는 순간들
반면에 Pulumi는 개발자 팀에서 진가를 발휘하더라고요. 제가 사이드 프로젝트로 홈랩 인프라를 Pulumi(Python)로 관리해봤는데, 이런 점이 진짜 좋았어요:
# Pulumi Python — 복잡한 로직도 그냥 Python으로
import pulumi
import pulumi_aws as aws
# 환경별 설정을 딕셔너리로 관리
env_configs = {
"production": {"instance_type": "t3.medium", "count": 3},
"staging": {"instance_type": "t3.small", "count": 1},
"dev": {"instance_type": "t3.micro", "count": 1},
}
config = pulumi.Config()
env = config.require("environment")
current_config = env_configs[env]
# 그냥 for 루프로 인스턴스 생성 — 이게 얼마나 자연스러운지!
instances = []
for i in range(current_config["count"]):
instance = aws.ec2.Instance(
f"web-server-{i}",
ami="ami-0c55b159cbfafe1f0",
instance_type=current_config["instance_type"],
tags={
"Name": f"web-server-{i}",
"Environment": env,
}
)
instances.append(instance)
# 결과 출력도 Python 리스트 컴프리헨션으로
pulumi.export("instance_ids", [inst.id for inst in instances])
이거 처음 써봤을 때 "드디어 됐다!" 싶었어요. 프로그래밍 언어의 모든 기능을 그대로 쓸 수 있으니까, 복잡한 조건 처리나 반복 작업이 훨씬 자연스럽거든요.
Pulumi가 특히 유리한 상황:
- 💡 팀이 개발자 중심일 때 — TypeScript, Python 등 이미 아는 언어로 바로 시작 가능
- 💡 인프라 로직이 복잡할 때 — 조건문, 반복문, 함수 등을 자유롭게 사용
- 💡 테스트 자동화가 중요할 때 — pytest, Jest 등 기존 테스트 도구 그대로 활용
- 💡 기존 코드베이스와 통합할 때 — 앱 코드와 인프라 코드를 같은 언어로 관리
Pulumi의 아픈 부분 ⚠️
근데 Pulumi도 완벽하진 않아요. 제가 겪은 몇 가지 불편한 점들:
- 레퍼런스 부족 — 문제 생겼을 때 구글링해도 Terraform만큼 자료가 안 나와요. 특히 엣지 케이스는 직접 디버깅해야 하는 경우가 많았음
- Pulumi Cloud 의존성 — 기본 상태 관리가 Pulumi Cloud를 통하는 방식이라, 자체 관리하려면 별도 설정이 필요
- 언어별 지원 수준 차이 — TypeScript 지원이 가장 성숙하고, 다른 언어는 업데이트 시점이 조금씩 달라요
- 팀 온보딩 — 인프라 엔지니어가 특정 프로그래밍 언어에 익숙하지 않으면 오히려 진입 장벽이 될 수 있음
Pulumi Cloud 콘솔에서 스택 상태와 리소스 배포 결과를 확인하는 화면
⚠️ 실전에서 주의해야 할 것들
Terraform 상태 파일(State File) 관리
Terraform 쓰면서 가장 많이 삽질하는 부분이 상태 파일 관리예요. 처음에 로컬에 `terraform.tfstate` 파일 두고 팀에서 같이 쓰다가 충돌 났던 경험, 한 번쯤은 다들 있으실 거예요 ㅎㅎ
# 반드시 원격 백엔드 설정하세요!
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "production/terraform.tfstate"
region = "ap-northeast-2"
encrypt = true
dynamodb_table = "terraform-state-lock" # 동시 수정 방지용 잠금
}
}
DynamoDB로 상태 잠금(State Locking) 설정 안 해두면, 두 사람이 동시에 apply 실행할 때 상태 파일이 꼬일 수 있어요. 이거 한 번 겪어보면 절대 안 잊어버리게 됩니다 😅
Pulumi 스택(Stack) 분리 전략
Pulumi에서는 환경별로 스택을 분리하는 게 기본 패턴인데, 초반에 이걸 제대로 설계 안 하면 나중에 꽤 고생해요.
# Pulumi 스택 생성 및 관리
pulumi stack init production
pulumi stack init staging
pulumi stack init dev
# 현재 스택 확인
pulumi stack ls
# 스택 전환
pulumi stack select production
# 배포 미리보기 (Terraform의 plan에 해당)
pulumi preview
# 실제 배포
pulumi up
💡 팁: Pulumi에서 환경별 설정값은 `pulumi config set`으로 관리하세요. 민감한 값은 `--secret` 플래그로 암호화해서 저장할 수 있어요.
# 일반 설정값
pulumi config set aws:region ap-northeast-2
pulumi config set environment production
# 민감한 정보는 암호화 저장
pulumi config set --secret db_password "super-secret-password"
Terraform 라이선스 변경 이후 고민
앞서 언급했지만, 2023년 Terraform의 BSL 라이선스 전환은 꽤 큰 이슈였어요. 이 때문에 OpenTofu라는 오픈소스 포크가 Linux Foundation 산하에서 시작됐고, 많은 조직에서 마이그레이션을 고려하기 시작했죠. Pulumi로 넘어가는 팀들도 일부 있었고요.
만약 상업적 사용이나 Terraform 기반 서비스 제공을 고려하고 있다면, BSL 1.1 조건을 법무팀과 함께 꼼꼼히 검토하시길 권장합니다.
결국 뭘 선택해야 할까요? — 상황별 가이드
제가 컨설팅이나 팀 내 논의에서 자주 받는 질문이 "그래서 뭐 써야 해요?"인데요. 정답은 없지만, 제 기준을 공유해 드릴게요.
✅ Terraform을 선택하면 좋은 경우
- 팀에 인프라 전문가 비율이 높고, HCL에 거부감이 없을 때
- 커뮤니티 레퍼런스와 안정성이 최우선일 때
- Terraform Registry의 공개 모듈을 적극 활용하고 싶을 때
- 기존 Terraform 코드베이스가 있는 팀에 합류할 때
- 비교적 단순한 인프라 구성이 주를 이룰 때
✅ Pulumi를 선택하면 좋은 경우
- 팀이 소프트웨어 개발자 중심이고, 특정 언어에 능숙할 때
- 인프라 로직이 복잡해서 프로그래밍적 표현이 필요할 때
- 인프라 코드에 유닛 테스트를 적용하고 싶을 때
- 앱 코드와 인프라 코드를 같은 언어로 통합 관리하고 싶을 때
- 라이선스 이슈에서 자유로운 완전 오픈소스 도구가 필요할 때
팀 상황과 프로젝트 특성에 따른 Terraform vs Pulumi 선택 가이드 인포그래픽
자주 묻는 질문 (FAQ)
Q. Terraform에서 Pulumi로 마이그레이션할 수 있나요?
네, Pulumi에서 공식적으로 변환 도구를 제공해요. `pulumi convert --from terraform` 명령으로 기본적인 리소스 변환이 가능합니다. 완벽하지는 않지만, 간단한 구성은 꽤 잘 변환되더라고요. 다만 복잡한 모듈이나 커스텀 프로바이더는 수동 작업이 필요할 수 있어요.
Q. 둘 다 멀티 클라우드(Multi-Cloud)를 지원하나요?
둘 다 AWS, Azure, GCP 등 주요 클라우드 프로바이더를 지원합니다. Terraform은 프로바이더 생태계가 더 방대하고, Pulumi는 Terraform 프로바이더를 브리지(Bridge)해서 쓸 수 있어서 커버리지 차이가 많이 줄어들었어요.
Q. Pulumi는 무료인가요?
Pulumi 자체는 오픈소스(Apache 2.0)로 무료입니다. Pulumi Cloud의 경우 개인 사용은 무료 플랜이 있고, 팀 협업 기능이나 고급 기능은 유료 플랜이 필요해요. 자체 백엔드(S3, Azure Blob Storage 등)를 사용하면 Cloud 없이도 운영 가능합니다.
Q. 둘 다 Kubernetes(쿠버네티스) 관리에 적합한가요?
네, 둘 다 Kubernetes 리소스 관리를 지원합니다. 다만 Kubernetes 전용으로는 Helm이나 Kustomize와의 조합이 더 일반적이에요. 클라우드 인프라(EKS 클러스터 생성 등)와 Kubernetes 리소스를 함께 관리할 때 IaC 도구가 유용하게 쓰입니다.
마무리 — 결국 중요한 건 팀과 컨텍스트
Pulumi vs Terraform 비교를 오래 해봤지만, 솔직히 말씀드리면 둘 다 훌륭한 IaC 도구입니다. 어느 쪽이 "객관적으로 더 좋다"라고 말하기가 어려워요.
제 개인적인 포지션을 말씀드리면:
- 🏢 엔터프라이즈 환경, 인프라 팀 주도 → Terraform (안정성, 레퍼런스, 생태계)
- 🚀 스타트업, 개발자 팀, 복잡한 로직 → Pulumi (유연성, 언어 친숙도)
- 🏠 홈랩, 개인 프로젝트 → 둘 다 배워보세요! 경험치 쌓기엔 최고
저는 요즘 홈랩은 Pulumi(Python)로, 업무 환경은 Terraform으로 관리하고 있어요. 두 도구를 병행하면서 각각의 강점을 더 명확하게 느끼게 됐달까요.
혹시 이미 둘 중 하나를 쓰고 계신 분들은, 반대편 도구도 간단한 사이드 프로젝트로 한번 써보시길 추천드려요. 비교해봐야 진짜 차이가 느껴지거든요.
다음 글에서는 Terraform 상태 관리와 원격 백엔드 설정을 더 깊이 다뤄볼 예정이에요. Terraform 쓰다가 상태 파일로 삽질한 경험이 있으신 분들이라면 도움이 될 겁니다. 이전 글에서 다뤘던 클라우드 인프라 자동화 기초도 함께 참고해보세요!
질문이나 의견은 댓글로 남겨주세요. 저도 아직 배우는 중이라, 여러분의 경험도 궁금합니다 😊
'IT > Cloud' 카테고리의 다른 글
| [클라우드 비용 관리] Terraform Cloud 비용 최적화: RUM 모델과 절감 전략 (0) | 2026.05.10 |
|---|---|
| [Cloud] Cloudflare Workers 실전 가이드: 서버리스 엣지 컴퓨팅 활용 전략 (1) | 2026.05.09 |
| [Cloud] Podman vs Docker: Rootless 컨테이너 보안 및 활용 가이드 (1) | 2026.05.09 |
| [Cloud] Ansible 클라우드 보안 자동화: 취약점 관리 및 규정 준수 가이드 (1) | 2026.05.05 |
| [Cloud] AWS 비용 최적화: EC2, S3, RDS 절감 전략 및 Cost Explorer 활용 가이드 (1) | 2026.05.01 |
| [Cloud] Terraform으로 AWS/GCP/Azure 멀티 클라우드 환경 구축 가이드 (0) | 2026.04.29 |