refactor: 구조 변경

This commit is contained in:
donghyeon-ka
2026-08-28 17:24:26 +09:00
parent a6f6c663e0
commit b8626946b1
192 changed files with 2251 additions and 206 deletions
+146
View File
@@ -0,0 +1,146 @@
# Getting Started
이 문서는 이 저장소가 채택한 공통 템플릿 구조와 새 catalog 항목 생성 규칙을
설명합니다. Project GitOps의 실제 입문 순서와 운영 gate는
[`intern-guide.md`](intern-guide.md)와 runbook을 우선합니다.
## 예제를 먼저 확인하기
실제 파일을 만들기 전에 두 예제를 설계 참고 자료로 사용합니다.
1. `examples/minimal`에서 단일 환경의 canonical 폴더와 조립 방식을 확인합니다.
2. 다음 명령으로 platform과 app이 cluster root에서 합쳐지는 결과를 확인합니다.
```bash
kubectl kustomize examples/minimal/gitops/clusters/dev/main
```
3. 다중 계정·리전·클러스터가 필요하면 `examples/scaled/README.md`에서 경로와
state 분리 기준을 선택합니다.
4. 실제 파일은 `examples`에서 복사하지 않고 각 책임 폴더의 `_template`에서
생성합니다.
```text
examples ──▶ 구조 선택 ──▶ _template 복사 ──▶ live/clusters 구현
```
## 1. 프로젝트 선택 기록
구현을 추가하기 전에 다음 항목을 결정하고 `docs/decisions`에 ADR을 작성합니다.
- cloud/on-prem provider와 account/project 구조
- Terraform, OpenTofu, Pulumi 등 IaC 엔진
- Kustomize 중심 또는 Helm 사용 범위
- Flux 또는 Argo CD 등 GitOps 컨트롤러
- External Secrets 또는 SOPS 등 비밀 관리 방식
- admission policy와 observability 운영 범위
선택하지 않은 도구의 빈 폴더를 모두 만들 필요는 없습니다.
Terraform/OpenTofu를 선택했다면 IaC 파일을 추가하기 전에 다음 선택 파일을
만들고 한 값만 활성화합니다.
```bash
cp infrastructure/.iac-engine.example infrastructure/.iac-engine
```
`.iac-engine`에는 주석을 제외하고 `tofu` 또는 `terraform` 한 줄만 남깁니다.
선택한 도구와 version을 CI에도 설치·고정하고 project-specific
`init -backend=false`/`validate` 검사를 추가합니다.
## 2. 프로젝트 메타데이터 설정
1. `README.md`의 제목과 프로젝트 범위를 바꿉니다.
2. `.github/CODEOWNERS.example`을 실제 소유자로 수정한 뒤 `CODEOWNERS`로
이름을 바꿉니다.
3. `SECURITY.md`에 조직의 보안 연락처와 SLA를 추가합니다.
4. 선택한 도구 버전을 프로젝트의 버전 관리 방식으로 고정합니다.
5. branch protection과 required check를 설정합니다.
## 3. Foundation bootstrap
`bootstrap/foundation` 아래에 remote state, locking, 초기 CI identity 등
다른 인프라가 의존하는 최소 구성을 작성합니다.
Foundation은 일반 infrastructure state와 분리하고 변경 권한을 좁게 유지합니다.
이미 조직 공통 foundation이 있다면 이 폴더에는 외부 의존 계약과 초기화 방법만
문서화해도 됩니다.
## 4. Infrastructure 작성
작은 프로젝트는 component와 live root만으로 시작합니다.
```bash
cp -R infrastructure/components/_template infrastructure/components/kubernetes-cluster
mkdir -p infrastructure/live/dev
cp -R infrastructure/live/_template infrastructure/live/dev/cluster
```
동일한 조합이 여러 환경에서 반복될 때만 stack을 추가합니다.
```bash
cp -R infrastructure/stacks/_template infrastructure/stacks/cluster
```
`live` root마다 backend/state를 분리하고, provider credential은 파일에 저장하지
않습니다.
## 5. Desired state 조립
필요한 catalog 템플릿을 복사합니다.
```bash
cp -R gitops/platform/_template gitops/platform/core
cp -R gitops/apps/_template gitops/apps/example-api
mkdir -p gitops/clusters/dev
cp -R gitops/clusters/_template gitops/clusters/dev/main
```
component의 `base`에 공통값을 두고, 환경 차이가 있을 때만 overlay를 추가합니다.
마지막으로 cluster `kustomization.yaml`이 사용할 component를 참조하게 합니다.
복사된 README의 `__REPLACE_ME_*__` 값을 모두 실제 메타데이터로 바꿉니다.
controller에 연결하기 전에 실제 cluster root를 로컬에서 렌더해 확인합니다.
## 6. GitOps bootstrap
desired-state root가 준비되고 클러스터가 생성되면 `bootstrap/gitops`에서 GitOps
컨트롤러 하나를 선택해 설치합니다. 이 단계에는 다음만 포함합니다.
- controller 설치 또는 설치 선언
- repository/OCI source 연결
- 검증된 `gitops/clusters/<...>` root reconcile 연결
- controller가 secret manager에 접근하는 최소 identity
일반 platform addon과 application은 이 단계에 넣지 않습니다.
## 7. 검증
```bash
make doctor
make check
kubectl kustomize examples/minimal/gitops/clusters/dev/main
kubectl kustomize gitops/clusters/dev/main
```
프로젝트에서 실제 IaC, Helm, policy 파일을 추가하면 필요한 validator를
`scripts/validate.sh`에 명시적으로 추가하고 CI에서도 같은 `make check`를
호출합니다. 도구가 없을 때 조용히 성공하도록 만들지 않습니다.
첫 환경은 다음 조건을 모두 만족하면 완료된 것으로 봅니다.
- 실제 `live` root의 대상, state, owner와 실행 절차가 작성되어 있다.
- 실제 cluster root가 필요한 catalog base/overlay를 참조하고 비어 있지 않다.
- cluster root 렌더 결과와 IaC plan이 리뷰 가능하다.
- GitOps bootstrap root가 `_template`이 아닌 실제 cluster root를 가리킨다.
- 비밀 관리, rollback과 담당자 연락 경로가 문서화되어 있다.
## 8. 운영 준비
- production apply 승인 및 concurrency lock
- backup/restore와 disaster recovery runbook
- cluster와 addon upgrade 정책
- secret rotation과 접근 감사
- alert routing과 담당자
- 비용, 용량, SLO 기준
운영 준비가 끝나기 전에는 예제 값을 production에 재사용하지 않습니다.
+117
View File
@@ -0,0 +1,117 @@
# Intern guide
## 이 저장소의 역할
이 저장소는 Project Auth를 예제로 한 독립 GitOps reference lab입니다.
애플리케이션 소스나 범용 production platform이 아닙니다. 현재 지원하는
환경은 `dev-k3s` 하나입니다.
서로 다른 세 reconciliation 경계를 먼저 구분합니다.
1. Gitea `main`이 승인된 desired-state revision을 저장합니다.
2. Argo CD가 그 revision의 Kubernetes 리소스를 지속적으로 맞춥니다.
3. Terraform이 승인된 실행 환경에서 Vault API 객체를 관리합니다.
GHCR은 빌드된 image를 보관할 뿐 desired-state source가 아닙니다. Argo
CD가 Terraform을 실행하지 않으며 CI가 routine deployment를 위해
`kubectl apply`를 호출하지 않습니다. Secret 값도 Git이나 Terraform을
통과하지 않습니다.
## 디렉터리를 고르는 법
- 여러 system이 공유하는 cluster capability: `gitops/platform`
- Project Auth bounded context 전용 backing service:
`gitops/apps/systems/auth-system`
- 별도 source repository에서 빌드하는 서버: `gitops/apps/workloads`
- Dev namespace, digest, host, Vault annotation: `gitops/clusters/dev-k3s/overlays`
- Vault API 객체: `infrastructure/components``infrastructure/live`
현재 Vault는 platform shared service, PostgreSQL과 Keycloak은 auth-system,
`auth-server``api-server`는 workload입니다. 설치 순서나 중요도로
`foundation`을 만들지 않습니다. 자세한 기준은
`docs/architecture/repository-taxonomy.md`에 있습니다.
## 안전한 변경 흐름
1. `refactor/...`, `feat/...`, `fix/...` branch에서 변경합니다.
2. `make validate`를 실행합니다.
3. Rendered manifest 또는 Terraform plan을 검토합니다.
4. 내부 Gitea에 PR을 생성합니다.
5. 승인 후 `main`에 merge합니다.
6. Kubernetes 변경은 열린 `autoSync` gate에서 Argo CD가 반영합니다.
7. Terraform 변경은 해당 state identity로 별도 승인 후 실행합니다.
새 ApplicationSet element는 기본적으로 `autoSync: "false"`로 추가합니다.
선행 controller, Vault 구성, secret과 database 준비를 확인한 별도 PR에서
gate를 엽니다. Gate가 닫혀도 수동 Sync는 가능하므로 임의로 누르지
않습니다.
금지 사항:
- `.terraform`, state, plan, tfvars, Vault init JSON, token commit
- 동일 Vault path/resource를 두 state에서 관리
- Secret payload를 Terraform resource/data source로 관리
- Image promotion workflow의 `main` 직접 push
- Routine CI 또는 사람의 직접 `kubectl apply`
- Production skeleton이나 이름뿐인 production Application 추가
- Hook을 사용하는 Application에 `ApplyOutOfSyncOnly=true` 적용
- `autoSync: "true"` 전환 PR에서 누적 live diff를 확인하지 않음
## 자주 쓰는 읽기 전용 명령
최종 dev manifest 렌더링:
```bash
kubectl kustomize gitops/clusters/dev-k3s/overlays/workloads/auth-server
kubectl kustomize gitops/clusters/dev-k3s/overlays/systems/auth-system
kubectl kustomize gitops/clusters/dev-k3s/overlays/platform/vault
```
전체 정적 검증:
```bash
make validate
```
Backend 없이 Terraform configuration 검증:
```bash
for terraform_root in vault-foundation vault-workloads vault-database; do
terraform_data_dir="$(mktemp -d)"
TF_DATA_DIR="$terraform_data_dir" \
terraform -chdir="infrastructure/live/dev-k3s/${terraform_root}" \
init -backend=false -input=false -lockfile=readonly
TF_DATA_DIR="$terraform_data_dir" \
terraform -chdir="infrastructure/live/dev-k3s/${terraform_root}" validate
rm -rf "$terraform_data_dir"
done
```
일반적으로는 같은 검사를 포함한 `make validate`를 사용합니다. 위 예는
provider data를 repository의 `.terraform`에 남기지 않습니다.
실제 plan은 승인된 backend와 identity를 준비한 뒤 수행합니다.
```bash
make terraform-plan \
TF_ROOT=vault-workloads \
BACKEND_CONFIG=.local/terraform-backend/dev-k3s/vault-workloads.s3.hcl
```
Image 승격은 Gitea `Promote Dev Image by Pull Request` workflow에 정확한
`sha256:` digest를 전달합니다. Workflow는 전용 branch와 PR을 만들며
`main`에 직접 쓰지 않습니다.
## 읽는 순서
1. `README.md`
2. `docs/architecture/repository-taxonomy.md`
3. `docs/architecture/deployment.md`
4. `docs/architecture/argocd.md`
5. `docs/architecture/secret-trust.md`
6. `docs/architecture/terraform.md`
7. `docs/decisions/`
8. 수행하려는 작업의 runbook
2026-07-26 리팩터링은 repository에서만 구현·검증했으며 실제 cluster에
적용하지 않았습니다. Live migration을 연습 과제로 실행하지 않습니다.