본문 바로가기
IT/Cloud

[Cloud] Terraform vs Pulumi: IaC 도구 비교 및 선택 가이드

by 수누다 2026. 5. 19.

IaC 도구 선택, 생각보다 중요한 문제입니다

인프라를 코드로 관리하기 시작한 게 벌써 7~8년 전 일인데요, 그때만 해도 Terraform(테라폼)이 사실상 IaC(Infrastructure as Code, 인프라를 코드로 관리하는 방식)의 표준처럼 여겨졌습니다. 그런데 최근 몇 년 사이에 Pulumi(풀루미)가 치고 올라오면서 팀 내에서도 "우리 이제 Pulumi로 갈아타야 하는 거 아니야?"라는 얘기가 슬슬 나오기 시작하더라고요.

저도 처음엔 "또 새로운 도구 나왔네" 하고 넘겼는데, 실제로 홈랩에서 Terraform과 Pulumi를 나란히 써보면서 생각이 좀 바뀌었습니다. 단순히 어느 게 더 낫다는 게 아니라, 팀 상황과 사용 목적에 따라 선택이 완전히 달라지는 도구라는 걸 직접 느꼈거든요.

이 글에서는 Terraform vs Pulumi를 실제 사용 경험을 바탕으로 비교해드리려고 합니다. IaC 도구 비교 글들이 많긴 한데, 대부분 공식 문서 요약 수준이라 아쉬웠거든요. 실무에서 어떤 차이가 나는지 한번 풀어볼게요.

▲ Terraform과 Pulumi — 둘 다 훌륭한 IaC 도구지만, 철학이 다릅니다

Terraform과 Pulumi, 각각 어떤 도구인가요?

Terraform — HCL로 선언하는 인프라

Terraform은 HashiCorp(해시코프)가 만든 오픈소스 IaC 도구입니다. HCL(HashiCorp Configuration Language, 해시코프 설정 언어)이라는 자체 DSL(Domain-Specific Language, 도메인 특화 언어)을 사용하는데요. 쉽게 말해 "이런 인프라가 존재해야 해"라고 선언하면 Terraform이 현재 상태와 비교해서 필요한 작업을 자동으로 처리하는 방식입니다.

2014년에 처음 나왔으니까 이미 10년이 넘었네요. 덕분에 Provider(프로바이더, 클라우드/서비스 연동 플러그인) 생태계가 정말 풍부합니다. AWS, GCP, Azure는 물론이고 GitHub, Datadog, PagerDuty까지 대부분의 주요 서비스를 지원해요.

다만 2023년에 HashiCorp가 라이선스를 BSL(Business Source License)로 변경하면서 커뮤니티가 반발했습니다. 이 때문에 OpenTofu(오픈토푸)라는 포크 프로젝트도 생겼어요. 라이선스 정책은 도구 선택 시 꼭 고려해야 할 사항입니다.

Pulumi — 진짜 프로그래밍 언어로 인프라를

Pulumi는 2018년에 등장한 IaC 도구인데, Terraform과는 완전히 다른 접근을 취합니다. Python, TypeScript, Go, C#, Java 같은 범용 프로그래밍 언어로 인프라를 정의한다는 게 핵심이에요.

처음 들었을 땐 "그게 뭐가 좋아?" 싶었는데, 직접 써보니 차이가 꽤 크더라고요. 반복문, 조건문, 함수, 클래스 같은 프로그래밍 언어의 모든 기능을 인프라 코드에 그대로 쓸 수 있거든요. 기존 패키지 생태계(npm, pip 등)도 활용 가능합니다.

State(상태, 인프라의 현재 상태를 저장하는 파일) 관리는 Pulumi Cloud를 이용하거나, AWS S3나 Azure Blob 같은 스토리지에 직접 저장할 수 있어요.

핵심 철학 차이: 선언형 vs 명령형

Terraform과 Pulumi의 가장 근본적인 차이는 선언형(Declarative) vs 명령형(Imperative) 접근 방식입니다. 이 차이가 실제 개발 경험에 큰 영향을 미칩니다.

항목 Terraform Pulumi
언어 HCL (자체 DSL) Python, TypeScript, Go, C#, Java 등
패러다임 선언형 (Declarative) 선언형 + 명령형 혼합
State 관리 로컬 파일 또는 원격 Backend Pulumi Cloud 또는 자체 Backend
라이선스 BSL 1.1 (2023년 변경) Apache 2.0
Provider 생태계 매우 풍부 (수천 개) 풍부 (Terraform Provider 재활용 가능)
학습 곡선 HCL 문법 별도 학습 필요 기존 언어 지식 활용 가능
테스트 별도 도구 필요 (Terratest 등) 기존 테스트 프레임워크 활용
IDE 지원 플러그인 필요 언어별 IDE 지원 그대로

실제 코드로 보는 Terraform vs Pulumi 차이

말로만 설명하면 와닿지 않으니까, 같은 작업을 두 도구로 작성한 코드를 비교해볼게요. AWS S3 버킷 3개를 만드는 간단한 예시입니다.

Terraform 방식 — count와 for_each

Terraform에서 여러 리소스를 만들려면 countfor_each를 써야 합니다. 처음엔 문법이 좀 낯설 수 있어요.

# variables.tf
variable "bucket_names" {
  type    = list(string)
  default = ["my-app-logs", "my-app-backups", "my-app-temp"]
}

# main.tf
resource "aws_s3_bucket" "app_buckets" {
  for_each = toset(var.bucket_names)
  bucket   = each.value
}

resource "aws_s3_bucket_versioning" "app_buckets" {
  for_each = aws_s3_bucket.app_buckets
  bucket   = each.value.id

  versioning_configuration {
    status = "Enabled"
  }
}

Pulumi 방식 — 프로그래밍 언어처럼

Pulumi에서는 Python으로 같은 작업을 이렇게 씁니다. 훨씬 직관적이죠?

import pulumi
import pulumi_aws as aws

bucket_names = ["my-app-logs", "my-app-backups", "my-app-temp"]

for bucket_name in bucket_names:
    bucket = aws.s3.Bucket(
        bucket_name,
        bucket=bucket_name
    )
    
    versioning = aws.s3.BucketVersioning(
        f"{bucket_name}-versioning",
        bucket=bucket.id,
        versioning_configuration={
            "status": "Enabled"
        }
    )

Pulumi 코드가 더 간결하고 읽기 쉽지 않나요? 이게 바로 범용 프로그래밍 언어를 쓰는 장점입니다. 변수, 함수, 클래스 등 익숙한 개념들을 그대로 활용할 수 있거든요.