refactor: reorganize GitOps control plane

This commit is contained in:
donghyeon-ka
2026-07-25 23:55:31 +09:00
parent d507ac6ee9
commit 293ee6fc97
191 changed files with 7046 additions and 9034 deletions
@@ -0,0 +1,88 @@
# Terraform v2 state migration
새 클러스터에는 이 runbook이 필요하지 않습니다. legacy local state 또는
이전 `provider-foundation`, `workload-foundation`, `workload-config`,
`database-config` remote state가 실제로 존재할 때만 수행합니다.
State 이동은 live object 삭제보다 위험할 수 있습니다. maintenance window와
독립 backup 없이 진행하지 않습니다.
## 목표
| 이전 state | 목표 |
|---|---|
| provider Transit Vault state | archive 후 provider Vault 폐기 절차에서 별도 처리 |
| workload foundation | `vault-core`의 기준 state |
| workload config | 소유 객체를 `vault-core`로 이동 |
| database config | `vault-database`로 backend key migration |
동일 클러스터 Transit Vault는 더 이상 desired state가 아닙니다. Terraform
state에서 먼저 삭제하거나 destroy하지 않습니다. snapshot과 seal dependency
해제 확인 후 별도 decommission 승인을 받아 처리합니다.
## 1. Inventory와 backup
모든 operator machine, runner, remote backend에서 state 위치를 확인합니다.
```bash
find . -type f \
\( -name 'terraform.tfstate*' -o -name '*.tfplan' \) \
-not -path './.git/*'
```
각 state를 `terraform state pull`로 encrypted offline custody에 저장하고
checksum을 기록합니다. backup에는 secret data가 포함될 수 있습니다.
## 2. Backend key migration
`workload-foundation` backend에 연결한 상태에서 새 `vault-core` backend
configuration으로 `terraform init -migrate-state`를 수행합니다.
`database-config`도 같은 방식으로 `vault-database` key로 이동합니다.
실제 backend 파일과 이전 key는 환경마다 다르므로 명령에 값을 하드코딩하지
않습니다. migration 전후 `terraform state pull` checksum과 `state list`
비교합니다.
## 3. Workload configuration ownership 이동
이전 `workload-config` state의 다음 객체를 `vault-core` state의 선언된
address로 이동합니다.
- application Vault policies
- workload Kubernetes auth roles
`terraform state mv -state=<source-backup> -state-out=<target-working-copy>`
사용해 offline copy에서 먼저 연습합니다. target address는 현재
`module.workload_policies``module.workload_roles``terraform state list`
결과를 기준으로 합니다. resource 이름을 추측하지 않습니다.
이동 후 두 state 모두 plan합니다.
- `vault-core`: 변경 없음 또는 address-only 이동
- legacy workload-config: 삭제할 live object 없음
두 plan 중 하나라도 destroy를 제안하면 중단하고 backup state를 복원합니다.
## 4. Database state
기존 database state가 없고 live Vault 객체만 존재할 때만 다음 import ID를
사용합니다.
```text
vault_database_secret_backend_connection.platform_postgres database/config/platform-postgres-dev
vault_database_secret_backend_role.auth_db_migration database/roles/auth-db-migration-dev
vault_database_secret_backend_role.postgres_operator database/roles/postgres-operator-dev
```
이미 다른 state에 address가 있으면 import하지 말고 state ownership을 먼저
이동합니다.
## 5. Cutover 완료 조건
- 두 목표 state가 remote backend와 locking을 사용
- 동일 Vault path가 두 state list에 나타나지 않음
- plan에 예상하지 않은 create/delete가 없음
- legacy state와 backup은 immutable archive
- repo와 runner에 local state/provider directory가 없음
검증이 끝나기 전 legacy backend를 삭제하지 않습니다.