Files
project-gitops/README.md
T

7.0 KiB

Project GitOps reference lab

Project Auth를 예제로 사용해 작은 팀의 GitOps 운영 경계를 학습하고 검증하는 독립 reference lab입니다. 범용 사내 플랫폼이나 애플리케이션 소스 monorepo가 아닙니다. 현재 지원 대상은 단일 dev-k3s 클러스터뿐입니다.

배포 기준 저장소는 내부 Gitea 한 곳입니다.

https://git.learn.hyeonworks.com/donghyeon.kang/project-gitops

auth-serverapi-server의 소스 저장소는 이미지를 빌드해 GHCR에 올립니다. 정상 promotion 계약은 검증된 immutable digest를 바꾸는 PR입니다. 현재 overlay에는 이관 전의 짧은 commit tag가 남아 있으며, registry를 검증할 credential 없이 임의 digest로 바꾸지 않았습니다. 다음 정상 promotion workflow가 digest로 전환합니다.

Kubernetes desired state는 Argo CD가, Vault API 객체는 Terraform이 각각 관리합니다. KV secret 값은 어느 쪽에도 저장하지 않습니다.

지원 범위

대상 상태
dev-k3s 지원하는 단일 노드 개발 환경
production 설계되지 않았으며 overlay/Application이 없음
Istio 보류; 향후 ambient mode 도입 조건만 기록

현재 Vault, PostgreSQL, ingress는 TLS가 없는 개발 프로파일이며 single-node failure domain을 공유합니다. production 용도로 사용할 수 없습니다.

2026-07-26의 repository/ownership 리팩터링은 Git 작업 트리에만 설계하고 검증했습니다. 실제 클러스터에는 적용하지 않았으며, 기존 리소스의 소유권 이관은 관련 runbook과 별도 승인 없이 실행하면 안 됩니다.

제어 흐름

application CI -> GHCR digest -> GitOps PR -> validation -> main
                                                            |
                                                            v
                                              Argo CD ApplicationSet
                                                            |
                                                            v
                                                       Kubernetes

IaC PR -> Terraform plan -> approval -> one Vault state apply -> Vault API

Argo CD 최초 설치 뒤 bootstrap 전용 gitops-control-plane AppProject와 단일 root Application만 순서대로 직접 적용합니다. 이후 routine deployment는 Git 변경으로만 수행합니다. Terraform은 Argo CD hook이나 Config Management Plugin 안에서 실행하지 않습니다.

저장소 분류

bootstrap/argocd/       controller 버전, 제한된 AppProject와 단일 root seed
clusters/dev-k3s/
  overlays/
    platform/           공유 서비스의 dev-k3s 최종 구성
    systems/            bounded context system의 dev-k3s 최종 구성
    workloads/          first-party workload의 dev-k3s 최종 구성
platform/
  control-plane/argocd/ AppProject와 ApplicationSet inventory
  shared-services/      여러 system이 사용할 수 있는 cluster capability base
systems/                특정 bounded context가 소유하는 backing system base
workloads/              source repository가 따로 있는 실행 애플리케이션 base
iac/terraform/
  modules/              재사용 Vault 모듈
  live/dev-k3s/         vault-foundation, vault-workloads, vault-database roots
  backend/dev-k3s/      secret 없는 remote backend 예시
policies/vault/         Terraform이 읽는 Vault ACL 문서
hack/                   bootstrap, validation, dev Vault init entrypoint
docs/                   architecture, ADR, migration/operation runbook

분류는 제품 종류가 아니라 소비자, 소유자, 변경 주기로 결정합니다. Vault는 공유 capability이므로 platform/, Project Auth 전용 PostgreSQL과 Keycloak은 systems/auth-system/, 직접 빌드하는 서버는 workloads/에 속합니다. namespace, host, image digest, Vault role, NetworkPolicy 같은 클러스터별 값은 clusters/dev-k3s/overlays/에서 완결합니다.

자세한 판단 기준은 repository taxonomyADR 0007을 따릅니다.

Argo CD 단계 gate

Root Application은 platform/control-plane/argocd의 AppProject와 ApplicationSet을 소유합니다. 각 inventory 항목은 autoSync를 quoted string으로 명시해야 합니다. 새 항목이나 외부 준비 조건이 있는 항목은 autoSync: "false"로 시작하고, 선행 controller, Vault 구성, runtime secret, database 준비를 확인한 PR에서만 autoSync: "true"로 바꿉니다.

Control-plane sync wave는 AppProject(-10)를 ApplicationSet(-5)보다 먼저 생성할 뿐, generated Application의 readiness를 보장하지 않습니다. autoSync gate와 workload의 retry/idempotency가 실제 단계 전환을 담당합니다.

Terraform state

Root 소유 범위 routine 실행 권한
vault-foundation mounts, auth backends/config, delegated automation policy와 선택적 CI JWT roles 없음; bootstrap 또는 보안 관리자 승인 실행
vault-workloads workload ACL, Kubernetes auth role, 애플리케이션 Transit key workload 전용 short-lived identity
vault-database PostgreSQL connection과 auth-db-migration-dev dynamic role database 전용 short-lived identity

중요한 규칙은 다음과 같습니다.

  • Vault API 객체 하나는 정확히 한 state만 소유합니다.
  • Delegated state는 자신에게 권한을 부여하는 policy/login role을 만들지 않습니다. 그것은 vault-foundation이 소유합니다.
  • State 사이에 terraform_remote_state를 사용하지 않습니다.
  • KV payload, Vault init JSON, token, PostgreSQL password를 Git이나 Terraform state에 저장하지 않습니다.
  • Backend는 encryption, versioning, access control, locking을 제공해야 합니다.

주요 명령

make validate
make bootstrap KUBE_CONTEXT=<expected-context>

make terraform-plan \
  TF_ROOT=vault-foundation \
  BACKEND_CONFIG=.local/terraform-backend/dev-k3s/vault-foundation.s3.hcl

terraform-apply는 동일 입력과 APPROVE_APPLY=dev-k3s/<root>가 모두 있어야 실행되며 auto-approve를 사용하지 않습니다. 실제 bootstrap과 state 이동은 먼저 runbook의 중단 조건을 확인합니다.

문서