노트

Terraform

Terraform

인프라#tooling · 연결된 개념 6개

쉽게 말하면

Terraform은 건물 도면을 그려 두면 시공사가 지금 건물과 도면을 비교해 달라진 부분만 공사해 주는 거예요. 서버·버킷·도메인 같은 인프라를 화면에서 클릭해 만드는 대신 파일에 적어 두고 그대로 만들게 해요.

비유의 한계 도면만 있다고 '지금 뭐가 지어져 있는지' 장부가 저절로 생기진 않아요. state 파일이 그 장부라서 잃어버리거나 여럿이 동시에 고치면 꼬이고, 비밀값도 들어가니 git에 올리면 안 돼요.

Terraform은 클라우드와 온프렘 리소스를 사람이 읽는 설정 파일로 만들고, 바꾸고, 버전 관리하는 IaC(Infrastructure as Code) 도구다. 콘솔에서 클릭해 만들던 서버·스토리지·DNS 레코드를 코드로 적어 두면 같은 파일로 같은 인프라를 다시 만들 수 있고, 설정 파일을 git 같은 버전 관리 시스템에 올려 변경 이력을 남길 수 있다.

선언형과 프로바이더

  • .tf 설정 파일은 HCL(HashiCorp Configuration Language)로 쓴다. 여기에는 "어떤 순서로 만들지"가 아니라 "최종적으로 무엇이 있어야 하는지"를 적는다(선언형과 명령형 프로그래밍). Terraform이 거기까지 가는 단계를 계산하고, 리소스 간 의존 관계로 그래프를 만들어 서로 독립인 리소스는 병렬로 만들거나 고친다
  • 프로바이더(provider)는 각 플랫폼의 API에 연결하는 플러그인이다. API가 열려 있는 서비스라면 대부분 다룰 수 있고, 공개 프로바이더 수천 개가 Terraform Registry에 올라와 있다(2026 기준)
terraform {
  required_providers {
    vercel = {
      source  = "vercel/vercel"
      version = ">= 4.8"
    }
  }
}
 
# api_token을 생략하면 환경변수 VERCEL_API_TOKEN에서 읽는다
provider "vercel" {
  api_token = var.vercel_api_token
}
 
resource "vercel_project" "with_git" {
  name      = "example-project-with-git"
  framework = "nextjs"
  git_repository = {
    type = "github"
    repo = "vercel/some-repo"
  }
}

워크플로: Write → Plan → Apply

  1. Write: 위처럼 리소스를 적는다. 여러 프로바이더를 한 설정에 섞어도 된다
  2. Plan: terraform plan이 무엇을 create·update·destroy할지 실행 계획으로 보여 준다. 설정과 현재 상태가 이미 같으면 할 일이 없다고 보고한다
  3. Apply: 승인하면 terraform apply가 의존 순서를 지키며 계획을 실제로 적용한다

설정을 쓴 뒤 가장 먼저 terraform init으로 작업 디렉터리를 초기화한다. 이때 프로바이더 플러그인을 내려받고 state를 둘 백엔드를 준비한다. 여러 번 돌려도 설정이나 state를 지우지 않는다.

state: 실제 리소스와 설정의 대응표

Terraform은 "설정 속 이 resource 블록이 실제 어느 객체인지"를 state에 기록한다. 기본은 로컬 파일 terraform.tfstate이고 직전 상태는 terraform.tfstate.backup에 남는다. 공식 문서는 팀으로 쓸 때 state 잠금(locking)과 접근 제어를 지원하는 원격 백엔드나 HCP Terraform에 두라고 권한다. 잠금이 없으면 두 사람이 동시에 Terraform을 돌려 state가 깨질 수 있고, 로컬 state는 평문 파일이라 설정에 적은 비밀값이 그대로 들어가므로 git에 올리면 새어 나간다. 이 파일을 잃어버리면 설정과 실제 객체의 대응도 함께 사라진다. 공식 문서는 state 없이는 Terraform이 동작할 수 없다고 한다.

import: 이미 만든 리소스 끌어오기

대시보드로 먼저 만든 리소스는 state에 없으므로 Terraform이 관리하지 못한다. terraform import 명령은 실제 객체를 state에 묶어 주지만 설정은 만들어 주지 않아서, resource 블록을 먼저 손으로 써 둬야 한다.

terraform import vercel_project.example prj_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

설정까지 생성하려면 import 블록을 쓰고 terraform plan에 -generate-config-out 옵션을 주면 resource 블록을 만들어 준다. 원격 객체 하나는 resource 주소 하나에만 묶여야 한다. 같은 객체를 두 블록이 가리키면 안 된다.

관련 개념

원하는 상태를 적고 도구가 차이를 메운다는 점은 쿠버네티스 핵심 개념의 재조정과 같은 발상이고, 같은 설정을 다시 apply해도 이미 맞는 리소스는 건드리지 않는다는 점에서 멱등하다. 다만 Kubernetes 컨트롤러는 계속 돌지만 Terraform은 사람이 plan·apply를 돌릴 때만 맞춘다. 그 사이에 손으로 바꾼 것이 설정 드리프트다. .tf 파일을 git에 두고 거기서만 바꾸면 GitOps의 "git이 진실" 원칙을 인프라에 적용한 셈이다. 컨테이너 몇 개를 한 파일로 띄우는 Docker Compose가 앱 스택의 선언형 파일이라면, Terraform은 그 앱이 올라갈 인프라 쪽의 선언형 파일이다.

출처: What is Terraform? · Terraform 설정 언어 · terraform plan · 리소스 만들기·관리 개요 · terraform init · State · State의 목적 · State 잠금 · 민감 데이터 관리 · Import (CLI) · Import 개요(설정 언어) · Vercel 프로바이더 · HCL 저장소

연결된 개념

이 노트를 가리키는 문서

아직 없습니다.

뜻이 가까운 노트

  • Turborepo

    Turborepo는 JavaScript·TypeScript 모노레포의 태스크(빌드·린트·테스트)를 빠르게 돌리는 빌드 시스템이다. 기존 package.json 스크립트는 그대로 두고, 스크립트 사이의 의존 관계만 알려 주면 병렬 실행과 캐싱을 맡는다. 의도적으로 "빠른 실행과 캐시" 한 가지에 집중한다.

  • 모노레포

    모노레포는 여러 프로젝트·패키지를 하나의 저장소에 폴더로 나눠 함께 관리하는 방식이다. 프로젝트마다 저장소를 따로 두는 방식은 멀티레포(폴리레포)라고 부른다. 모노레포가 곧 하나의 거대한 앱(모놀리스, monolith)이라는 뜻은 아니다. 배포 단위는 여전히 따로일 수 있다.

  • useActionState와 폼 액션

    React 19에서는 <form action={함수}>에 함수를 바로 넘길 수 있고, useActionState가 그 액션의 대기 상태와 마지막 결과를 한 훅으로 관리한다. useState + onSubmit + 로딩 플래그로 짜던 패턴을 대체한다.

  • 컨테이너 네트워킹

    컨테이너는 각자 격리된 네트워크를 가지므로, 서로 통신하려면 같은 도커 네트워크에 붙인다. 같은 사용자 정의 네트워크(user-defined network) 안에서는 도커 내장 DNS(Domain Name System)가 컨테이너 이름(또는 별칭)을 IP로 풀어 주어, IP 대신 이름으로 접속한다.

  • 커맨드 패턴

    요청이나 작업을 실행 가능한 객체로 포장하는 패턴. 작업을 값처럼 저장·전달·대기열에 넣을 수 있게 되고, 되돌리기 같은 부가 연산을 붙일 수 있다.

보기 옵션