|
| 1 | +--- |
| 2 | +name: GCP Project Migration |
| 3 | +description: GCP 프로젝트 간 마이그레이션 (DB, Storage, Container Images, Terraform) |
| 4 | +--- |
| 5 | + |
| 6 | +# GCP Project Migration Skill |
| 7 | + |
| 8 | +이 스킬은 GCP 프로젝트를 한 프로젝트에서 다른 프로젝트로 완전 이전하는 작업을 안내합니다. |
| 9 | + |
| 10 | +## 사전 조건 |
| 11 | + |
| 12 | +1. **두 GCP 프로젝트** 모두에 대한 Owner/Editor 권한 |
| 13 | +2. **gcloud CLI** 설치 및 인증됨 |
| 14 | +3. **Docker** 설치됨 (컨테이너 이미지 이전용) |
| 15 | +4. 새 프로젝트에 **Terraform 인프라가 먼저 배포**되어 있어야 함 |
| 16 | + |
| 17 | +## 마이그레이션 순서 |
| 18 | + |
| 19 | +### Phase 1: API 활성화 |
| 20 | + |
| 21 | +새 프로젝트에서 필요한 API들을 활성화합니다: |
| 22 | + |
| 23 | +```bash |
| 24 | +gcloud services enable \ |
| 25 | + sqladmin.googleapis.com \ |
| 26 | + run.googleapis.com \ |
| 27 | + artifactregistry.googleapis.com \ |
| 28 | + iamcredentials.googleapis.com \ |
| 29 | + cloudtasks.googleapis.com \ |
| 30 | + pubsub.googleapis.com \ |
| 31 | + storage.googleapis.com \ |
| 32 | + compute.googleapis.com \ |
| 33 | + vpcaccess.googleapis.com \ |
| 34 | + aiplatform.googleapis.com \ |
| 35 | + --project=NEW_PROJECT_ID |
| 36 | +``` |
| 37 | + |
| 38 | +### Phase 2: 데이터베이스 마이그레이션 |
| 39 | + |
| 40 | +1. **Export from old project** |
| 41 | + ```bash |
| 42 | + # 구 프로젝트 계정으로 전환 |
| 43 | + gcloud config set account OLD_ACCOUNT@gmail.com |
| 44 | + |
| 45 | + # Cloud SQL 서비스 계정에 버킷 권한 부여 |
| 46 | + OLD_SA=$(gcloud sql instances describe OLD_INSTANCE --project=OLD_PROJECT --format="value(serviceAccountEmailAddress)") |
| 47 | + gcloud storage buckets add-iam-policy-binding gs://MIGRATION_BUCKET \ |
| 48 | + --member="serviceAccount:$OLD_SA" \ |
| 49 | + --role="roles/storage.objectAdmin" |
| 50 | + |
| 51 | + # DB 덤프 |
| 52 | + gcloud sql export sql OLD_INSTANCE gs://MIGRATION_BUCKET/dump.sql \ |
| 53 | + --database=pic2cook --project=OLD_PROJECT |
| 54 | + ``` |
| 55 | + |
| 56 | +2. **Import to new project** |
| 57 | + ```bash |
| 58 | + # 신 프로젝트 계정으로 전환 |
| 59 | + gcloud config set account NEW_ACCOUNT@gmail.com |
| 60 | + |
| 61 | + # 권한 부여 및 Import |
| 62 | + NEW_SA=$(gcloud sql instances describe NEW_INSTANCE --project=NEW_PROJECT --format="value(serviceAccountEmailAddress)") |
| 63 | + gcloud storage buckets add-iam-policy-binding gs://MIGRATION_BUCKET \ |
| 64 | + --member="serviceAccount:$NEW_SA" \ |
| 65 | + --role="roles/storage.objectViewer" |
| 66 | + |
| 67 | + gcloud sql import sql NEW_INSTANCE gs://MIGRATION_BUCKET/dump.sql \ |
| 68 | + --database=pic2cook --user=postgres --project=NEW_PROJECT |
| 69 | + ``` |
| 70 | + |
| 71 | +### Phase 3: GCS 버킷 마이그레이션 |
| 72 | + |
| 73 | +```bash |
| 74 | +# 구 계정에서 신 계정에 읽기 권한 부여 |
| 75 | +gcloud storage buckets add-iam-policy-binding gs://OLD_BUCKET \ |
| 76 | + --member="user:NEW_ACCOUNT@gmail.com" \ |
| 77 | + --role="roles/storage.objectViewer" |
| 78 | + |
| 79 | +# 신 계정에서 버킷 생성 및 동기화 |
| 80 | +gcloud storage buckets create gs://NEW_BUCKET --location=REGION --project=NEW_PROJECT |
| 81 | +gcloud storage rsync -r gs://OLD_BUCKET gs://NEW_BUCKET |
| 82 | +``` |
| 83 | + |
| 84 | +### Phase 4: 컨테이너 이미지 마이그레이션 |
| 85 | + |
| 86 | +```bash |
| 87 | +# Docker 인증 |
| 88 | +gcloud auth configure-docker OLD_REGION-docker.pkg.dev,NEW_REGION-docker.pkg.dev |
| 89 | + |
| 90 | +# 이미지 Pull -> Tag -> Push |
| 91 | +docker pull OLD_REGION-docker.pkg.dev/OLD_PROJECT/REPO/IMAGE:TAG |
| 92 | +docker tag OLD_REGION-docker.pkg.dev/OLD_PROJECT/REPO/IMAGE:TAG \ |
| 93 | + NEW_REGION-docker.pkg.dev/NEW_PROJECT/REPO/IMAGE:TAG |
| 94 | +docker push NEW_REGION-docker.pkg.dev/NEW_PROJECT/REPO/IMAGE:TAG |
| 95 | +``` |
| 96 | + |
| 97 | +### Phase 5: Terraform 변수 수정 |
| 98 | + |
| 99 | +`apps/infra/variables.tf` 파일 상단의 변수만 수정: |
| 100 | + |
| 101 | +```hcl |
| 102 | +variable "project_id" { |
| 103 | + default = "NEW_PROJECT_ID" # ← 변경 |
| 104 | +} |
| 105 | +
|
| 106 | +variable "region" { |
| 107 | + default = "asia-northeast1" # ← 필요 시 변경 |
| 108 | +} |
| 109 | +``` |
| 110 | + |
| 111 | +**수동 변경 필요**: |
| 112 | +- `provider.tf`의 `backend.bucket` (Terraform 제약) |
| 113 | + |
| 114 | +### Phase 6: GitHub Secrets 업데이트 |
| 115 | + |
| 116 | +Repository Settings > Secrets and variables > Actions에서: |
| 117 | + |
| 118 | +| Secret | 값 | |
| 119 | +| -------------------------------- | -------------------------------------------------------------------------------------------------------- | |
| 120 | +| `GCP_WORKLOAD_IDENTITY_PROVIDER` | `projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/pic2cook-pool/providers/github-provider` | |
| 121 | +| `GCP_SERVICE_ACCOUNT` | `pic2cook-deployer@NEW_PROJECT.iam.gserviceaccount.com` | |
| 122 | + |
| 123 | +값 조회: |
| 124 | +```bash |
| 125 | +# Project Number |
| 126 | +gcloud projects describe NEW_PROJECT --format="value(projectNumber)" |
| 127 | + |
| 128 | +# WIF Provider |
| 129 | +gcloud iam workload-identity-pools providers describe github-provider \ |
| 130 | + --workload-identity-pool=pic2cook-pool --location=global --project=NEW_PROJECT --format="value(name)" |
| 131 | +``` |
| 132 | + |
| 133 | +### Phase 7: 코드 변경 및 배포 |
| 134 | + |
| 135 | +1. `apps/api/src/lib/config.py`의 `gcs_bucket_name` 기본값 변경 |
| 136 | +2. 커밋 및 푸시 |
| 137 | +3. GitHub Actions가 자동 배포 |
| 138 | + |
| 139 | +## 자동화 스크립트 |
| 140 | + |
| 141 | +전체 데이터 마이그레이션을 한 번에 실행: |
| 142 | + |
| 143 | +```bash |
| 144 | +./.agent/skills/gcp-migration/scripts/migrate-gcp-project.sh \ |
| 145 | + --old-project OLD_PROJECT_ID \ |
| 146 | + --new-project NEW_PROJECT_ID \ |
| 147 | + --old-region us-central1 \ |
| 148 | + --new-region asia-northeast1 |
| 149 | +``` |
| 150 | + |
| 151 | +## 참조 문서 |
| 152 | + |
| 153 | +- [마이그레이션 가이드](docs/gcp-migration-guide.md) |
| 154 | +- [마이그레이션 스크립트](.agent/skills/gcp-migration/scripts/migrate-gcp-project.sh) |
| 155 | + |
| 156 | +## 체크리스트 |
| 157 | + |
| 158 | +- [ ] API 활성화 완료 |
| 159 | +- [ ] DB 마이그레이션 완료 |
| 160 | +- [ ] GCS 버킷 마이그레이션 완료 |
| 161 | +- [ ] 컨테이너 이미지 마이그레이션 완료 |
| 162 | +- [ ] Terraform variables.tf 수정 |
| 163 | +- [ ] GitHub Secrets 업데이트 |
| 164 | +- [ ] config.py 수정 및 푸시 |
| 165 | +- [ ] 배포 확인 및 테스트 |
0 commit comments