Terraform

Terraform
요약 다이어그램(직접 생성). 본문 내용은 공식 문서 근거 기반입니다.

Terraform + Kubernetes 운영 심화: ConfigMap 변경이 Pod에 반영되지 않는 장애 재현과 복구

이 글은 Terraform으로 Kubernetes 리소스를 관리할 때 자주 발생하는 ConfigMap 변경 미반영 문제를 재현하고, 공식 문서 근거에 맞춰 안전하게 복구하는 방법을 정리합니다.

1) 버전/전제

  • Terraform CLI: 1.6+ (lifecycle/replace 관련 기능 사용)
  • Terraform Kubernetes Provider: 2.x
  • Kubernetes: 1.29~1.33 범위 문서 기준
  • ConfigMap을 envFrom 또는 volumeMount로 주입하는 Deployment 운영 환경

핵심 전제: Kubernetes는 ConfigMap 변경 시 Pod를 자동 재생성하지 않습니다. Deployment의 Pod template이 바뀌어야 롤링 업데이트가 시작됩니다.

2) 핵심 개념

2-1. 왜 ConfigMap 변경만으로는 충분하지 않은가

ConfigMap 데이터가 바뀌어도 기존 Pod는 그대로 살아 있습니다. 특히 envFrom/env로 읽은 환경변수는 프로세스 시작 시점 값이라, Pod 재시작 전에는 최신값이 반영되지 않습니다.

2-2. 체크섬(annotation)으로 Deployment를 의도적으로 변경

Terraform에서 ConfigMap 데이터의 해시를 Deployment annotation에 넣으면, ConfigMap 값 변경 시 Pod template hash가 바뀌고 RollingUpdate가 자동으로 발생합니다.

Terraform apply 후 ConfigMap checksum 변경이 Deployment RollingUpdate를 유도하는 요청 흐름도
아키텍처/요청흐름 도식. 출처: 직접 제작(작성자, CC BY 4.0). | 직접 생성. 무단 사용 금지

2-3. 실전 스니펫 #1: Terraform 체크섬 기반 롤링 업데이트

resource "kubernetes_config_map_v1" "app_config" {
  metadata {
    name      = "app-config"
    namespace = "prod"
  }

  data = {
    FEATURE_X_ENABLED = "true"
    API_BASE_URL      = "https://api.example.com"
  }
}

resource "kubernetes_deployment_v1" "app" {
  metadata {
    name      = "app"
    namespace = "prod"
  }

  spec {
    replicas = 3

    selector {
      match_labels = {
        app = "app"
      }
    }

    template {
      metadata {
        labels = {
          app = "app"
        }

        annotations = {
          config_checksum = sha256(jsonencode(kubernetes_config_map_v1.app_config.data))
        }
      }

      spec {
        container {
          name  = "app"
          image = "ghcr.io/example/app:1.0.0"

          env_from {
            config_map_ref {
              name = kubernetes_config_map_v1.app_config.metadata[0].name
            }
          }
        }
      }
    }
  }
}

2-4. 실전 스니펫 #2: 장애 재현/검증 명령

# 1) 현재 Pod가 사용하는 값 확인
kubectl -n prod exec deploy/app -- printenv FEATURE_X_ENABLED

# 2) ConfigMap 값 변경(예: false)
kubectl -n prod patch configmap app-config 
  --type merge 
  -p '{"data":{"FEATURE_X_ENABLED":"false"}}'

# 3) Pod 재생성 없이 값이 그대로인지 확인(장애 재현)
kubectl -n prod exec deploy/app -- printenv FEATURE_X_ENABLED

# 4) 수동 복구(임시): 롤아웃 재시작
kubectl -n prod rollout restart deploy/app
kubectl -n prod rollout status deploy/app

3) 트레이드오프 (의사결정 표)

선택지 장점 단점 언제 선택
체크섬 annotation 자동 롤링 변경 누락 방지, 자동화 친화적, 재현성 높음 사소한 설정 변경도 롤링 발생 운영 표준 경로(권장)
수동 rollout restart 즉시 대응 가능, 구현 단순 사람 의존, 누락 리스크 큼 장애 시 응급복구
애플리케이션 핫리로드 구현 무중단/재기동 최소화 가능 앱 복잡도 증가, 검증 비용 높음 매우 빈번한 설정 변경 서비스

4) 장애 재현/해결

장애 징후 원인 조치
ConfigMap은 변경됐는데 기능 플래그가 구버전으로 동작 Pod 재생성이 없어서 env 값이 초기값 유지 체크섬 annotation 추가, 즉시 복구는 rollout restart
Terraform apply 성공인데 서비스 동작 변화 없음 Deployment pod template hash 불변 ConfigMap data 해시를 template.annotation에 연결
일부 Pod만 신설정 반영, 일부는 미반영 수동 재시작 중 중단/부분 적용 rollout status로 완료 확인, 자동 롤링으로 전환

5) 체크리스트

  • ConfigMap 변경 경로가 Terraform 단일 경로인지 확인(드리프트 방지)
  • Deployment template annotation에 checksum이 실제로 반영되는지 확인
  • kubectl rollout status로 롤링 완료를 자동 검증
  • ReadinessProbe 실패 시 자동 롤백/중단 시나리오를 사전 점검
  • 긴급 대응 Runbook에 rollout restart 포함

6) 공식 링크 (원문 근거)

요약하면, Terraform + Kubernetes 조합에서 설정 변경의 신뢰성을 올리려면 ConfigMap 변경 이벤트를 Deployment template 변경으로 변환해야 합니다. 체크섬 annotation은 구현 난이도 대비 운영 효과가 가장 좋은 기본 해법입니다.

7) Terraform 프로젝트 구조 베스트 프랙티스

프로젝트 규모에 따라 디렉터리 구조가 달라야 합니다. 아래는 중규모(서비스 3개+, 환경 3개) 프로젝트에 적합한 구조입니다.

terraform-project/
├── modules/                    # 재사용 가능한 모듈
│   ├── vpc/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── eks/
│   └── rds/
├── environments/               # 환경별 설정
│   ├── dev/
│   │   ├── main.tf            # 모듈 호출
│   │   ├── terraform.tfvars   # 환경 변수
│   │   └── backend.tf         # S3 backend
│   ├── staging/
│   └── prod/
├── .github/
│   └── workflows/
│       └── terraform.yml      # CI/CD
└── README.md

8) 자주 쓰는 Terraform 명령어 치트시트

# 기본 워크플로우
terraform init              # 프로바이더/모듈 다운로드
terraform plan -out=plan    # 변경 사항 미리보기 (파일로 저장)
terraform apply plan        # 저장된 plan 적용
terraform destroy           # 전체 리소스 삭제

# 상태 관리
terraform state list                    # 관리 중인 리소스 목록
terraform state show aws_instance.app   # 특정 리소스 상세
terraform state mv old_name new_name    # 리소스 이름 변경 (재생성 방지)
terraform state rm aws_instance.legacy  # 상태에서 제거 (리소스는 유지)

# 디버깅
terraform plan -target=aws_instance.app # 특정 리소스만 plan
terraform refresh                        # 실제 상태와 동기화
TF_LOG=DEBUG terraform plan             # 상세 로그 출력

# 포맷팅 & 검증
terraform fmt -recursive                # 코드 포맷팅
terraform validate                       # 문법 검증

# Import (기존 리소스 가져오기)
terraform import aws_instance.app i-1234567890abcdef0

9) .tfvars와 변수 우선순위

Terraform 변수는 여러 곳에서 설정할 수 있고, 우선순위를 이해해야 의도치 않은 값 적용을 방지할 수 있습니다.

변수 우선순위 (낮음 → 높음)
━━━━━━━━━━━━━━━━━━━━━━━
1. variable 블록의 default 값
2. terraform.tfvars 파일
3. *.auto.tfvars 파일 (알파벳순)
4. -var-file="custom.tfvars" 플래그
5. -var="key=value" 플래그
6. TF_VAR_key 환경 변수

10) 관련 글

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux