HCL (HashiCorp 구성 언어)

갱신 2026-08-03

한눈에 요약

세 요소가 전부다

Terraform 구성을 작성하는 선언형 언어다. 공식 문서는 문법이 블록·인수·표현식 세 요소가 전부라고 정리한다. 언어의 주목적은 리소스 선언이고, 나머지 기능은 전부 그것을 유연하게 만드는 보조다 27.

아래는 그 세 요소를 실제 구성 파일 수준에서 풀어 쓴 것이다 29.

블록 구조

블록타입 "라벨1" "라벨2" {
  인자 = 값
}

라벨 개수는 블록 타입마다 정해져 있다 — resource는 2개(리소스 타입, 이름), variable은 1개, terraform은 0개다 29.

자주 쓰는 최상위 블록

블록 역할
terraform Terraform 자체 설정(버전 제약, backend)
provider AWS 등 공급자 설정
resource 내가 만드는 인프라
data 이미 있는 것 조회 — 만들지도 지우지도 않음
variable 입력값
output 출력값, terraform output으로 추출

이 6종은 소형 구성에서 실제로 쓰이는 집합이고 언어가 지원하는 최상위 블록의 전부는 아니다 — 공식 문서는 module(자식 모듈 호출)과 로컬 값도 언어 구성 요소로 다룬다 27.

resource와 data

resource "aws_s3_bucket" "site" {
  bucket = var.site_bucket_name
}

data "aws_route53_zone" "main" {
  name = var.domain      # 검색 조건
}

리소스 타입(aws_s3_bucket)은 공급자가 정하고, 두 번째 라벨(site)은 구성 안에서만 통하는 이름이다. 참조는 타입.이름.속성 형태(aws_s3_bucket.site.arn)이며, data 블록은 참조할 때 data. 접두어가 필수다(data.aws_route53_zone.main.zone_id). aws_iam_policy_document처럼 클라우드 API를 전혀 호출하지 않고 JSON 정책을 HCL로 쓰게 해 주는 순수 계산용 data 소스도 있다 29.

variable과 output

variable 블록에 default가 없으면 값 입력이 필수가 되고, 값은 terraform.tfvars 파일이나 -var="domain=x.com" 플래그로 주입한다. 참조는 var.<이름>. output은 배포판 ID처럼 CI로 넘겨야 할 값을 밖으로 노출한다 29. 이 변수(입력)·출력 쌍이 곧 Terraform 모듈의 인터페이스라는 것이 공식 문서의 설명이다 27.

provider alias

기본 provider 하나에 별칭 provider를 여러 개 붙일 수 있고, 별칭을 쓰려면 리소스 쪽에서 명시해야 한다 29.

provider "aws" { region = "ap-northeast-2" }   # 기본

provider "aws" {
  alias  = "us_east_1"
  region = "us-east-1"
}

resource "aws_acm_certificate" "site" {
  provider = aws.us_east_1     # 이 줄이 없으면 기본 provider 사용
}

CloudFront가 쓰는 인증서는 반드시 us-east-1 리전에 있어야 해서 이 패턴이 필요하다 (2026-08 기준).

인수 vs 중첩 블록

=의 유무로 구분한다 — enabled = true는 인수, origin { ... }은 중첩 블록이다. 중첩 블록은 같은 블록 안에서 여러 번 반복할 수 있다 29.

메타 인수

모든 resource에 공통으로 붙는 인수들이다 29.

depends_on = [aws_s3_bucket.site]   # 명시적 순서. 보통 불필요
count      = 3                       # 개수만큼 복제
for_each   = { ... }                 # map/set 순회. each.key / each.value
provider   = aws.us_east_1           # provider 지정

lifecycle {
  create_before_destroy = true       # 지우기 전에 새로 만듦(인증서 무중단 교체)
  prevent_destroy       = true       # 삭제 차단
  ignore_changes        = [tags]     # 해당 속성 변경 무시
}

표현식

파일 이름은 의미가 없다

Terraform은 디렉터리 안의 *.tf를 전부 하나로 합쳐 읽는다. acm.tf·s3.tf처럼 나누는 것은 순전히 사람이 보기 편하라는 관례다 29. 블록 순서에 의미가 없다는 공식 문서의 선언형 서술과 같은 이야기의 파일 단위 버전이다 27.

참조가 곧 실행 순서

버킷 정책이 배포판의 ARN을 참조하면, 그 참조 때문에 Terraform이 배포판을 먼저 만들고 정책을 나중에 붙인다. 종속성 그래프가 참조에서 자동으로 만들어지므로 depends_on을 손으로 쓸 일은 거의 없다 29 27. 이것이 코드형 인프라의 선언형 특성이 문법 수준에서 드러나는 지점이다 — 순서를 사람이 쓰는 것이 아니라 관계에서 도출된다.

관련 명령

작성한 구성은 세 명령으로 다룬다 29 27.

공식 문서의 Write-Plan-Apply 코어 워크플로가 명령 수준에서는 이 셋으로 나타난다.

함께 읽기