Terraform엔 “이벤트 리스너” 같은 실시간 트리거는 없어.
대신 계획/적용(plan/apply) 시점에 “무엇이 바뀌면 무엇을 다시 만들지(Replace)”를 선언하는 방식으로 트리거를 구성.
lifecycle.replace_triggered_by — “저게 바뀌면 나도 새로 만들기”terraform_data.triggers_replace — “이 값이 바뀌면 내가 갈아끼워짐”null_resource.triggers — 과거의 표준(요즘은 terraform_data 권장)lifecycle.replace_triggered_by — “A가 바뀌면 B도 교체”userdata.sh가 바뀌면 EC2를 새로 만들기locals {
userdata_sha = filesha256("${path.module}/userdata.sh")
}
# 1) 파일 해시 변화 → 이 리소스가 교체됨(아래 2번에서 연결고리로 사용)
resource "terraform_data" "app_spec" {
triggers_replace = { userdata = local.userdata_sha }
}
# 2) EC2는 app_spec이 교체될 때마다 "나도 교체"
resource "aws_instance" "web" {
ami = data.aws_ssm_parameter.al2023.value
instance_type = "t3.micro"
subnet_id = var.public_subnet_id
user_data = file("${path.module}/userdata.sh")
lifecycle {
replace_triggered_by = [terraform_data.app_spec]
}
}
terraform apply -auto-approve
# userdata.sh 내용 변경
terraform plan # ← aws_instance.web replace planned
팁
replace_triggered_by에 넣을 수는 없어.terraform_data를 ‘연결고리’로 두는 패턴이 깔끔해.terraform_data.triggers_replace — “이 값이 바뀌면 나를 교체”triggers_replace 값이 바뀌면 자기 자신이 교체됨.locals {
artifact_sha = filesha256("${path.module}/app.zip")
}
resource "terraform_data" "redeploy" {
triggers_replace = { artifact = local.artifact_sha }
# 필요한 경우에만 사용 (로그에 비밀 노출 주의)
provisioner "local-exec" {
command = "echo 'artifact changed; do deploy step here'"
}
}
terraform apply
# app.zip 교체 또는 내용 변경
terraform plan # ← terraform_data.redeploy will be replaced
베스트 프랙티스
triggers_replace 값은 결정적(deterministic) 이어야 해.timestamp() 같은 값 넣으면 매번 교체 → 끝없는 흔들림)null_resource.triggers — 레거시 트리거(이해는 필수)null_resource + triggers로 “입력 값이 바뀌면 리소스를 교체→프로비저너 실행”을 많이 썼어.terraform_data가 권장 대체. 기존 코드 읽을 때만 이해해두면 충분.resource "null_resource" "build" {
triggers = {
artifact = filesha256("${path.module}/app.zip")
}
provisioner "local-exec" {
command = "echo build because ${self.triggers.artifact}"
}
}
주의
triggers에 비결정적 값을 넣으면 항상 재실행(반복 churn).| 상황 | 추천 패턴 |
|---|---|
| 다른 리소스가 교체되면 나도 반드시 교체 | lifecycle.replace_triggered_by |
| 파일/아티팩트/입력 값 변화 감지 자체가 필요 | terraform_data.triggers_replace |
| 레거시 코드 유지/읽기 | null_resource.triggers (새 코드에선 지양) |
timestamp() 금지sensitive/시크릿 매니저 사용, provisioner 명령행 주의depends_on 또는 replace_triggered_by로 연결plan -out → apply plan.binQ. “트리거”가 실시간 이벤트처럼 동작하나요?
A. 아니요. Terraform은 plan/apply 사이클에서만 동작. 파일이 바뀐 즉시 자동 실행 같은 건 없어.
Q. replace_triggered_by에 파일 해시를 바로 넣으면 안 돼요?
A. 불가능. 대신 위 예제처럼 terraform_data를 연결고리로 사용하면 돼.
Q. Provisioner는 꼭 필요할 때만?
A. 맞아. 설치/설정은 cloud-init(UserData)/Ansible/Packer가 더 안전하고 재현성 좋아.
Terraform의 트리거는 “무엇이 바뀌면 무엇을 다시 만들지”를 선언하는 기술.
교체 연동은replace_triggered_by, 변화 감지는terraform_data.triggers_replace,
레거시는null_resource.triggers—이 세 가지면 실전에서 다 커버된다.