본문 바로가기
IT & Tech 정보

IaC Drift as Code: Terraform Cloud Sentinel + OPA Gatekeeper + Argo CD Self-Heal

by 지식과 지혜의 나무 2025. 5. 29.
반응형


기반 자동화 인프라 드리프트 감지 및 복구 파이프라인


🎯 목표

“코드로 정의된 인프라(Infrastructure-as-Code)가 언제나 실제 클러스터/클라우드 상태와 일치하도록”
1. 드리프트(Drift) 감지
2. 정책 위반(Policy Violation) 식별
3. 자동 복구(Self-Healing)
4. 모든 과정을 GitOps 이력으로 기록
까지 완전 자동화하는 엔드-투-엔드 워크플로우를 구축합니다.



⚙️ 핵심 구성 요소

계층 도구 / 기술 역할
정책 관리 Terraform Cloud Sentinel + OPA Gatekeeper Drift 정책·보안 정책 코드화 (Sentinel policy / Rego)
드리프트 감지 Terraform Cloud + Atlantis terraform plan 자동 실행 → Drift 여부 판정
클러스터 정책 OPA Gatekeeper Kubernetes 리소스 정책 검증 및 위반 시 Admission 차단
배포 동기화 Argo CD GitOps 기반 Manifest 동기화 ↔ 클러스터 상태 일관성 검증 및 복구
자동 복구 Argo CD Self-Heal + Webhook Operator Drift 감지 시 Git 커밋 또는 Rollout restart로 자동 복구
알림 & 기록 GitHub Actions + Slack Drift 발생·복구 이력 Git 커밋·PR + Slack 알림




🏗️ 워크플로우

flowchart TD
  subgraph Drift Detection
    A[Git Push IaC 변경] --> B[Atlantis plan/pr]
    B --> C{terraform plan 결과}
    C -- Drift Detected --> D[Create DriftReport CR]
    C -- No Drift --> E[Merge PR, 정상 상태 유지]
  end

  D --> F[GitHub Actions: Commit drift-report.yaml]
  F --> G[Argo CD Sync]
  G --> H[OPA Gatekeeper validate resources]
  H -- Violation --> I[Admission Reject / Slack Alert]
  H -- OK --> J[Argo CD Self-Heal: Git Manifest → 클러스터 복구]
  J --> K[Slack “Self-Heal 완료” 알림]




🧪 실전 예제

1) Terraform Sentinel Policy (drift.sentinel)

# drift.sentinel
import "tfplan/v2" as tfplan

main = rule {
  length(tfplan.resource_changes) is 0
}

• terraform plan 결과 리소스 변경 없이 length == 0이어야 통과

2) OPA Gatekeeper ConstraintTemplate (no-privileged-pods)

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8snoPrivileged
spec:
  crd:
    spec:
      names:
        kind: K8sNoPrivileged
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8snoPrivileged
        violation[{"msg": msg}] {
          pod := input.review.object.spec.containers[_]
          pod.securityContext.privileged == true
          msg := sprintf("Privileged 컨테이너(%v)는 허용되지 않습니다", [input.review.object.metadata.name])
        }

3) DriftReport CRD

apiVersion: infra.example.com/v1
kind: DriftReport
metadata:
  name: infra-drift-2025-06-01
spec:
  resources:
    - aws_s3_bucket.my_app_data
    - kubernetes_deployment.webapp
status:
  recovered: false

4) Argo CD Self-Heal 설정

spec:
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - Validate=true

• selfHeal: true옵션으로 클러스터가 Git 상태와 다를 때 자동 복구

5) Webhook Operator 복구 트리거 (Python)

@app.route('/drift-webhook', methods=['POST'])
def on_drift():
    report = request.json
    # GitHub Actions에 repository_dispatch 호출
    requests.post(
      'https://api.github.com/repos/myorg/infra/dispatches',
      headers={'Authorization': f'token {GITHUB_TOKEN}'},
      json={'event_type':'drift-detected'}
    )
    return '', 200

6) GitHub Actions: Drift 복구 커밋

on:
  repository_dispatch:
    types: [drift-detected]
jobs:
  record-drift:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: |
          timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
          echo "- report: infra-drift-${timestamp}.yaml" >> drift-log.yaml
          git add drift-log.yaml
          git commit -m "Drift detected at ${timestamp}"
          git push

• Argo CD가 최신 Git 커밋과 비교 후 Self-Heal 자동 실행



✅ 기대 효과
• 실시간 Drift 감지: Terraform Cloud + Sentinel로 계획(plan) 단계부터 Drift 방지
• 정책 위반 차단: OPA Gatekeeper로 클러스터 진입 전 보안·컴플라이언스 지킨다
• 무인 Self-Healing: GitOps Self-Heal로 Drift 발생 즉시 자동 복구
• 투명한 이력: Drift 및 복구 이력을 Git 커밋, Slack 알림으로 모두 기록



🔧 확장 포인트
• Drift Remediation PR: 복구가 복잡한 리소스는 자동으로 PR 생성 후 수동 승인
• Drift Dashboard: Grafana + Elastic Kibana로 Drift 발생률·추세 시각화
• Multi-Region Drift: 중앙 레코드와 리모트 리전 상태 Drift 비동기 비교
• Cost Drift 방지: 예산 초과 리소스 변경(예: 인스턴스 타입 업그레이드)도 차단

반응형