
Terraform 설치 과정은 공식 문서를 따라가면 충분하다고 보고, 여기서는 Kubernetes 환경에서 Terraform을 어떻게 구성하고 쓰는지에 집중해서 정리한다.
보통 프로젝트 구조는 이렇게 나눈다.
project/
├ main.tf # 실제 리소스 정의
├ variables.tf # 변수 정의 (하드코딩 방지)
├ outputs.tf # 생성된 값 출력
└ terraform.tfstate # 인프라 상태 파일 (자동 생성)
이 구조로 나누면:
Terraform은 인프라의 현재 상태를 terraform.tfstate 파일로 저장한다.
이 파일을 기준으로 Terraform은 이런 걸 계산한다.
즉, tfstate는 Terraform 입장에서 싱글 소스 오브 트루스(Single Source of Truth) 역할을 한다.
특징 요약:
plan/apply가 꼬일 수 있다.Terraform의 중요한 성질:
같은 코드를 가지고
terraform apply를 여러 번 실행해도
결과 인프라 상태는 항상 동일해야 한다.
No changes만 출력하고 아무것도 안 한다.그래서 인프라를 항상 원하는 상태로 유지할 수 있고,
단순 YAML + kubectl 조합보다 더 안정적인 운영이 가능하다.
Kubernetes를 Terraform으로 다룰 때 가장 중요한 포인트:
kubectl apply는 서버 쪽에서 YAML을 머지(merge) 하는 방식그래서:
kubectl edit으로 바꿔 버리면terraform apply 할 때 충돌·되돌림이 발생할 수 있다.실습 전에 깨끗하게 맞추고 시작하려면:
kubectl delete deployment --all
kubectl delete service --all
kubectl delete ingress --all
같은 식으로 기존 리소스를 지우고 Terraform으로 올리는 흐름이 안전하다.
variables.tf에는 자주 바뀌는 값들을 변수로 빼서 관리한다.
예시:
variable "image_vue" {
default = "limu810/k8s-vue-ing:latest"
}
variable "image_boot" {
default = "limu810/k8s-boot-ing:latest"
}
variable "replicas_vue" {
default = 1
}
variable "replicas_boot" {
default = 1
}
장점:
Terraform이 만든 리소스의 특정 값을 output으로 노출하면,
나중에 자동화 스크립트나 다른 도구에서 쉽게 가져다 쓸 수 있다.
예시:
output "vue_service_ip" {
value = kubernetes_service.vue002ser.spec[0].cluster_ip
}
이렇게 정의해두면:
terraform output
terraform output vue_service_ip
로 Service의 ClusterIP를 바로 확인할 수 있다.
운영·모니터링 자동화에서 굉장히 자주 쓰이는 패턴이다.
main.tf에는 실제 리소스를 정의한다.
provider "kubernetes" {
config_path = "~/.kube/config"
}
예시 구조:
kubernetes_deployment → Vue/Spring Boot Deployment 정의kubernetes_service → 각 Deployment에 대응하는 Service 정의kubernetes_ingress_v1 → nginx Ingress로 경로 기반 라우팅Terraform 리소스 구조는 Kubernetes YAML과 거의 1:1 대응된다.
metadata.namespec.replicasspec.template.metadata.labelsspec.template.spec.containers[...]등 대부분이 그대로 HCL로 옮겨진 형태라
“YAML을 Terraform 문법으로 다시 쓴 것”이라고 생각하면 이해가 빠르다.
예를 들어 Vue Deployment 부분만 간단히 보면:
resource "kubernetes_deployment" "vue002dep" {
metadata {
name = "vue002dep"
}
spec {
replicas = var.replicas_vue
selector {
match_labels = {
app = "vue002kube"
}
}
template {
metadata {
labels = {
app = "vue002kube"
}
}
spec {
container {
name = "vue-container"
image = var.image_vue
port {
container_port = 80
}
}
}
}
}
}
YAML에 적을 내용을 HCL로 표현했다고 보면 된다.
Terraform 작업 순서는 항상 같다.
init → plan → apply
terraform init
.terraform/ 디렉터리 생성.terraform.lock.hcl로 provider 버전 고정terraform plan
실행 결과 예:
+ : 새로 생성~ : 수정- : 삭제코드가 의도한 대로 동작하는지 확인하는 단계다.
terraform apply
terraform.tfstate가 최신 상태로 업데이트된다.적용이 끝나면:
kubectl get all
terraform output
로 K8s 리소스와 output 값까지 함께 확인할 수 있다.
.terraform/
.terraform.lock.hcl
terraform.tfstate
Terraform의 강점은 “코드를 수정하면 인프라가 거기에 맞게 따라온다”는 점이다.
variables.tf에서 Vue replicas 값을 1 → 3으로 변경한다고 가정한다.
variable "replicas_vue" {
default = 3
}
이 한 줄로 “Vue 파드를 3개 유지하라”는 인프라 스펙이 바뀐다.
terraform plan
예상되는 출력:
~ resource "kubernetes_deployment" "vue002dep" {
spec.0.replicas: "1" => "3"
}
~는 기존 리소스를 수정한다는 의미terraform apply
그 후에 K8s에서 확인:
kubectl get deploy
kubectl get pods -l app=vue002kube
확인할 것:
app=vue002kube 라벨의 Pod가 3개 생성같은 코드 상태에서 한 번 더 실행해 본다.
terraform apply
출력 예:
No changes. Your infrastructure matches the configuration.
이게 바로 Terraform의 멱등성이다.
terraform destroy
테스트만 해보고 프로젝트 자체를 초기화하고 싶다면:
rm -rf .terraform*
rm terraform.tfstate*
이렇게 하면:
까지 깨끗하게 제거된다.
이 정리의 포인트를 한 줄로 요약하면:
Kubernetes 리소스를 YAML이 아니라 Terraform 코드로 선언하고,
init → plan → apply+tfstate기반으로 멱등하게 관리하는 패턴을 익히는 것
여기에 variables, outputs, provider, state 개념까지 이해하면
실제 프로젝트에서 Terraform으로 K8s 인프라를 안정적으로 운영할 수 있는 기본기는 갖추게 된다.