[Brochal] ArgoCD 한 번의 복사-붙여넣기가 만든 100분 장애: IaC/GitOps에 “강제 안전장치”가 필요한 이유

도입부: EKS 업그레이드 테스트 클러스터를 IaC(Terraform)+GitOps(ArgoCD)로 만들다가, 설정 복사 실수 하나가 운영 ALB까지 건드리며 100분 장애로 이어졌습니다. 이 글에서는 사고 흐름을 정리하고, 다시는 같은 유형의 사고가 나지 않도록 ArgoCD·Terraform 단계에서 최소한으로 걸어야 할 “강제 가드레일”을 정리합니다.


사건 개요: 테스트 ArgoCD가 운영 ALB를 동기화해버린 날

상황은 단순했습니다.

  • EKS v1.34 업그레이드를 대비해 테스트 클러스터를 새로 만들었습니다.
  • 구성은 Terraform로 인프라를 만들고, 애플리케이션 배포는 ArgoCD로 동기화하는 형태였습니다.
  • 문제는 운영 환경 설정을 복사해 테스트 환경을 빠르게 만들면서, AWS Load Balancer Controller(ALB Controller) 설정의 식별자 값이 운영 값으로 남아있었던 것입니다.
    • 예: clusterName, vpcId 같은 값이 테스트가 아니라 운영을 가리키는 상태

그 결과 테스트 클러스터의 ArgoCD가 의도와 달리 운영 쪽 Load Balancer 리소스까지 “정상 상태로 맞추려” 동기화를 해버렸고, 서비스 접속 장애가 발생했습니다.

여기서 핵심은 “자동화가 잘못된 방향으로도 매우 성실하다”는 점입니다. 사람이 실수한 구성은, 도구가 훨씬 빠르고 광범위하게 반영합니다.


1차 장애: 운영 ALB 설정이 변경되며 트래픽이 비정상화

테스트 환경에서 배포한 매니페스트/Helm 값이 운영 식별자를 포함하고 있었고, 그 상태로 ArgoCD 동기화가 실행되며 운영 리소스에 영향이 갔습니다.

이 유형의 사고가 더 위험한 이유는, Kubernetes 내부 리소스만 꼬이는 게 아니라 AWS 상의 외부 리소스(ALB, Target Group 등) 까지 연쇄적으로 바뀐다는 점입니다. 특히 AWS Load Balancer Controller는 Ingress/Service 상태에 따라 AWS 리소스를 “적극적으로” 생성/수정/삭제합니다.


2차 사고: 테스트 Application 삭제를 했더니 운영 ALB가 삭제됨 (Finalizer)

문제를 정리하려고 테스트 ArgoCD Application을 삭제하는 과정에서 더 큰 문제가 터졌습니다.

  • Kubernetes 리소스에 Finalizer가 걸려 있는 경우, 리소스를 삭제할 때 컨트롤러가 “외부 리소스 정리”를 수행합니다.
  • 이번 케이스에서는 정리 대상이 테스트 리소스가 아니라, 이미 잘못 연결된 상태의 운영 ALB가 되어버렸고 결과적으로 운영 ALB가 삭제되는 2차 사고로 이어졌습니다.

즉,

  • “ArgoCD가 운영을 건드린다”에서 끝난 게 아니라
  • “삭제 동작이 운영 리소스 삭제로 연결된다”로 확장된 것입니다.

복구 과정: 컨트롤러 재기동, scheme/group 수정, DNS 갱신

복구는 대략 다음 흐름으로 진행되었습니다.

  1. 운영 AWS Load Balancer Controller 재기동
  2. Ingress/Controller 설정에서
    • scheme(internal) 같은 값
    • group 관련 설정
      을 올바르게 맞추는 작업
  3. DNS(CNAME) 갱신으로 트래픽 경로 복원

여기까지로 대부분의 도메인은 복구됐지만, 일부는 여전히 비정상이었습니다.


잔여 장애: TargetGroupBinding(CRD) 잔존으로 타깃 그룹이 재생성되지 않음

일부 도메인은 ALB가 다시 만들어졌는데도 타깃 그룹이 정상적으로 재생성되지 않았습니다. 원인은 다음과 같았습니다.

  • TargetGroupBinding 같은 CRD 리소스가 클러스터 내부에 잔존
  • 그 잔존 리소스가 컨트롤러의 reconciliation(재조정)을 방해하거나, 기대와 다른 상태를 “이미 존재하는 정상 상태”로 판단하게 만듦
  • 결국 수동으로 TargetGroupBinding을 삭제하고, Ingress를 재생성해 완전 복구

최종적으로 총 100분 장애로 마무리되었습니다.


왜 이런 일이 가능했나: “환경 분리”가 코드가 아니라 권한/경계로 강제되지 않았습니다

이번 사고를 겪고 제가 가장 크게 느낀 건 이 지점입니다.

  • 운영을 먼저 만들고
  • 운영 설정을 복사해 테스트를 만들면
  • 운영이 “정답 템플릿”이 되고, 작은 누락 하나가 운영 영향으로 증폭됩니다.

GitOps/IaC는 복사-붙여넣기를 쉽게 만들지만, 동시에 복사 실수의 폭발 반경도 키웁니다.
그래서 “조심하자”가 아니라 “실수해도 운영을 못 건드리게”를 목표로 해야 합니다.


최소 세트 가드레일: ArgoCD·Terraform 단계에서 강제로 막아야 할 것들

1) (최우선) AWS 계정/권한 경계로 운영-테스트를 끊습니다

가장 강력한 가드레일은 이것입니다.

  • 운영과 테스트를 AWS 계정 자체로 분리하면,
  • 테스트 클러스터의 IRSA/IAM Role이 운영 리소스를 삭제하거나 수정하는 경로가 구조적으로 사라집니다.

계정 분리가 어렵다면 최소한:

  • 테스트용 IAM Role이 운영 VPC/ALB/Hosted Zone을 만질 수 없도록
  • 리소스 ARN 조건, 태그 조건, 허용 리전/서비스 제한 등을 촘촘히 거는 쪽으로 가야 합니다.

2) Terraform은 “하드코딩 값” 대신 “생성된 리소스 출력값으로만 연결”을 강제합니다

대화에서 정리된 방향처럼, 저도 이 접근이 현실적인 대안이라고 봅니다.

  • vpcId, clusterName, hosted zone id 같은 값이 코드에 상수로 남아 있으면 복사 실수로 섞일 확률이 매우 높습니다.
  • Terraform에서 리소스를 생성하고, 그 output을 다음 리소스 입력으로 연결하는 구조로 만들면 “운영 값을 복사해서 남기는 문제”가 크게 줄어듭니다.

핵심은 “입력값 누락 시 실패”입니다.

  • 기본값으로 운영 값이 들어가면 안 됩니다.
  • 환경별로 반드시 달라야 하는 값은 미입력 시 plan/apply가 실패하도록 만드는 게 안전합니다.

3) ArgoCD auto-sync는 “최종 검증 이후”에 켭니다 (또는 단계적으로 확장합니다)

사용자 코멘트처럼, auto-sync를 너무 일찍 켜면 “틀린 선언”이 즉시 반영되어 피해가 커집니다.

추천 흐름은 다음 중 하나입니다.

  • 초기에는 manual sync + diff 확인을 강제하고, 안정화 이후 auto-sync로 전환
  • 또는 auto-sync를 켜더라도
    • prune(삭제) 비활성화
    • self-heal 비활성화
    • 특정 리소스(예: Ingress, CRD, cluster-scoped) sync 제한
      처럼 “파괴 반경”을 줄여 단계적으로 확장

4) ArgoCD Project에서 “repo 허용”만으로는 부족하고, 목적지(destination)도 강제해야 합니다

“허용된 repo만 사용”은 공급망 통제에는 좋지만, 이번 사고처럼 repo 안에 운영 식별자가 들어가 있으면 막지 못합니다.

그래서 ArgoCD Project는 최소한:

  • 배포 가능한 cluster(=destination) 제한
  • 배포 가능한 namespace 제한
    을 강제해야 합니다.

즉 “어디서 온 코드인가”뿐 아니라 “어디로 배포되는가”를 같이 잠가야 합니다.

5) Admission 정책(OPA Gatekeeper/Kyverno 등)으로 운영 식별자 패턴을 차단합니다

운영 식별자가 Manifest/Helm values에 들어오는 것 자체를 막는 방법도 현실적인 가드레일입니다.

예를 들어:

  • alb.ingress.kubernetes.io/group.name에 운영 prefix가 들어가면 거부
  • clusterNameprod-* 패턴이면 거부
  • 특정 HostedZone/ARN 패턴이면 거부

이 방식은 “사람이 실수해도 apply 자체가 실패”하기 때문에, 마지막 방어선으로 특히 효과가 큽니다.


제가 얻은 결론: 자동화는 “속도”보다 “경계 강제”가 먼저입니다

이번 장애는 도구(Terraform, ArgoCD, ALB Controller)가 문제가 아니라, 환경 경계가 강제되지 않은 상태에서 자동화를 너무 빨리 연결한 문제에 가깝습니다.

정리하면 다음 한 문장으로 귀결됩니다.

  • IaC/GitOps는 강력하지만, 운영/테스트를 “논리”가 아니라 “권한과 정책”으로 분리하지 않으면 운영 자원도 의도치 않게 변경·삭제될 수 있습니다.

마무리

복사-붙여넣기로 환경을 늘리는 방식은 초기 속도는 빠르지만, 한 번의 누락이 운영 장애로 직결될 수 있습니다. 운영/테스트 분리를 “사람의 기억”이 아니라 “권한·정책·검증 단계”로 강제하는 최소 세트 가드레일부터 먼저 깔아두는 걸 추천합니다.


참고 자료

1 Like