بنقرة واحدة
gcp-project-migration
Migration between GCP Projects (DB, Storage, Container Images, Terraform)
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Migration between GCP Projects (DB, Storage, Container Images, Terraform)
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Act as a technical co-founder to turn a product idea into a shippable v1. Use when a user asks to build an app/product, ship an MVP, launch, or wants a technical cofounder style workflow (discovery, scope, plan, staged build, polish, handoff).
Comprehensive backend development skill for building scalable backend systems using Python (FastAPI), Postgres, Redis, and more. Includes API design, database optimization, security implementation, and performance tuning.
Expert guidance for Next.js Cache Components and Partial Prerendering (PPR). PROACTIVE ACTIVATION when cacheComponents config is detected.
When the user wants to create competitor comparison or alternative pages for SEO and sales enablement. Also use when the user mentions 'alternative page,' 'vs page,' 'competitor comparison,' 'comparison page,' '[Product] vs [Product],' '[Product] alternative,' or 'competitive landing pages.' Covers four formats: singular alternative, plural alternatives, you vs competitor, and competitor vs competitor. Emphasizes deep research, modular content architecture, and varied section types beyond feature tables.
Refactor high-complexity React components. Use when complexity metrics are high or to split monolithic UI.
Automates the creation of detailed, well-formatted Pull Requests using the GitHub CLI. Parses conventional commits to generate titles and descriptions.
| name | GCP Project Migration |
| description | Migration between GCP Projects (DB, Storage, Container Images, Terraform) |
This skill guides you through the process of fully migrating from one GCP project to another.
Enable required APIs in the new project:
gcloud services enable \
sqladmin.googleapis.com \
run.googleapis.com \
artifactregistry.googleapis.com \
iamcredentials.googleapis.com \
cloudtasks.googleapis.com \
pubsub.googleapis.com \
storage.googleapis.com \
compute.googleapis.com \
vpcaccess.googleapis.com \
aiplatform.googleapis.com \
--project=NEW_PROJECT_ID
Export from old project
# Switch to old project account
gcloud config set account OLD_ACCOUNT@gmail.com
# Grant bucket permissions to Cloud SQL service account
OLD_SA=$(gcloud sql instances describe OLD_INSTANCE --project=OLD_PROJECT --format="value(serviceAccountEmailAddress)")
gcloud storage buckets add-iam-policy-binding gs://MIGRATION_BUCKET \
--member="serviceAccount:$OLD_SA" \
--role="roles/storage.objectAdmin"
# Dump DB
gcloud sql export sql OLD_INSTANCE gs://MIGRATION_BUCKET/dump.sql \
--database=database_name --project=OLD_PROJECT
Import to new project
# Switch to new project account
gcloud config set account NEW_ACCOUNT@gmail.com
# Grant permissions and Import
NEW_SA=$(gcloud sql instances describe NEW_INSTANCE --project=NEW_PROJECT --format="value(serviceAccountEmailAddress)")
gcloud storage buckets add-iam-policy-binding gs://MIGRATION_BUCKET \
--member="serviceAccount:$NEW_SA" \
--role="roles/storage.objectViewer"
gcloud sql import sql NEW_INSTANCE gs://MIGRATION_BUCKET/dump.sql \
--database=database_name --user=db_username --project=NEW_PROJECT
# Grant read permission to new account from old account
gcloud storage buckets add-iam-policy-binding gs://OLD_BUCKET \
--member="user:NEW_ACCOUNT@gmail.com" \
--role="roles/storage.objectViewer"
# Create and sync bucket in new account
gcloud storage buckets create gs://NEW_BUCKET --location=REGION --project=NEW_PROJECT
gcloud storage rsync -r gs://OLD_BUCKET gs://NEW_BUCKET
# Docker Authentication
gcloud auth configure-docker OLD_REGION-docker.pkg.dev,NEW_REGION-docker.pkg.dev
# Image Pull -> Tag -> Push
docker pull OLD_REGION-docker.pkg.dev/OLD_PROJECT/REPO/IMAGE:TAG
docker tag OLD_REGION-docker.pkg.dev/OLD_PROJECT/REPO/IMAGE:TAG \
NEW_REGION-docker.pkg.dev/NEW_PROJECT/REPO/IMAGE:TAG
docker push NEW_REGION-docker.pkg.dev/NEW_PROJECT/REPO/IMAGE:TAG
Modify only the variables at the top of the apps/infra/variables.tf file:
variable "project_id" {
default = "NEW_PROJECT_ID" # ← Change
}
variable "region" {
default = "your_region" # ← Change if necessary
}
Manual Changes Required:
backend.bucket in provider.tf (Terraform limitation)In Repository Settings > Secrets and variables > Actions:
| Secret | Value |
|---|---|
GCP_WORKLOAD_IDENTITY_PROVIDER | projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/your-pool/providers/github-provider |
GCP_SERVICE_ACCOUNT | your-deployer@NEW_PROJECT.iam.gserviceaccount.com |
Retrieve Values:
# Project Number
gcloud projects describe NEW_PROJECT --format="value(projectNumber)"
# WIF Provider
gcloud iam workload-identity-pools providers describe github-provider \
--workload-identity-pool=your-pool --location=global --project=NEW_PROJECT --format="value(name)"
gcs_bucket_name default value in apps/api/src/lib/config.pyRun full data migration at once:
./.agent/skills/gcp-migration/scripts/migrate-gcp-project.sh \
--old-project OLD_PROJECT_ID \
--new-project NEW_PROJECT_ID \
--old-region your_old_region \
--new-region your_new_region
Symptoms:
Is the server running on that host and accepting TCP/IP connections?
Cause: A VPC Connector is required for Cloud Run Jobs to access Cloud SQL Private IP.
Resolution:
# 1. Enable VPC Access API
gcloud services enable vpcaccess.googleapis.com --project=NEW_PROJECT_ID
# 2. Check VPC Connector
gcloud compute networks vpc-access connectors list \
--region=REGION \
--project=NEW_PROJECT_ID
# 3. Create VPC Connector (if missing, use same network as Cloud SQL)
gcloud compute networks vpc-access connectors create CONNECTOR_NAME \
--region=REGION \
--network=NETWORK_NAME \
--range=10.9.0.0/28 \
--project=NEW_PROJECT_ID
# 4. Attach VPC Connector to Cloud Run Job
gcloud run jobs update JOB_NAME \
--region=REGION \
--project=NEW_PROJECT_ID \
--vpc-connector=CONNECTOR_NAME \
--vpc-egress=private-ranges-only
Symptoms:
VPC connector and direct VPC can not be used together
Resolution: Remove Direct VPC first, then add VPC Connector:
# Remove Direct VPC
gcloud run jobs update JOB_NAME \
--region=REGION \
--project=NEW_PROJECT_ID \
--clear-network
# Add VPC Connector
gcloud run jobs update JOB_NAME \
--region=REGION \
--project=NEW_PROJECT_ID \
--vpc-connector=CONNECTOR_NAME \
--vpc-egress=private-ranges-only
Symptoms:
FATAL: password authentication failed for user "username"
Resolution:
# Check Cloud SQL user list
gcloud sql users list \
--instance=INSTANCE_NAME \
--project=NEW_PROJECT_ID
# Reset password (if needed)
gcloud sql users set-password USERNAME \
--instance=INSTANCE_NAME \
--project=NEW_PROJECT_ID \
--password="NEW_PASSWORD"
Symptoms:
pydantic_core._pydantic_core.ValidationError: Field required
jwt_secret_key
Resolution: Environment variables required for Migration Job:
DATABASE_URL - PostgreSQL connection stringJWT_SECRET_KEY - JWT signing secretIMPORTANT: Use --update-env-vars to preserve existing environment variables:
# WRONG: Overwrites all existing environment variables
gcloud run jobs update JOB_NAME --set-env-vars="KEY=value"
# CORRECT: Adds/Updates while keeping existing environment variables
gcloud run jobs update JOB_NAME --update-env-vars="KEY=value"
Full process for manually fixing the Migration Job:
# 1. Enable VPC Access API
gcloud services enable vpcaccess.googleapis.com --project=NEW_PROJECT_ID
# 2. Check Cloud SQL Private IP
DB_IP=$(gcloud sql instances describe INSTANCE_NAME \
--project=NEW_PROJECT_ID \
--format="value(ipAddresses[0].ipAddress)")
echo "Cloud SQL Private IP: $DB_IP"
# 3. Create VPC Connector (same network as Cloud SQL)
gcloud compute networks vpc-access connectors create default-connector \
--region=REGION \
--network=default \
--range=10.9.0.0/28 \
--project=NEW_PROJECT_ID
# 4. Remove Direct VPC (if exists)
gcloud run jobs update JOB_NAME \
--region=REGION \
--project=NEW_PROJECT_ID \
--clear-network
# 5. Connect VPC Connector + Set Env Vars
gcloud run jobs update JOB_NAME \
--region=REGION \
--project=NEW_PROJECT_ID \
--vpc-connector=default-connector \
--vpc-egress=private-ranges-only \
--update-env-vars="DATABASE_URL=postgresql+asyncpg://USER:PASS@${DB_IP}:5432/DBNAME,JWT_SECRET_KEY=YOUR_JWT_SECRET"
# 6. Execute Migration
gcloud run jobs execute JOB_NAME \
--region=REGION \
--project=NEW_PROJECT_ID
# 7. Check Status
EXECUTION_ID=$(gcloud run jobs executions list \
--job=JOB_NAME \
--region=REGION \
--project=NEW_PROJECT_ID \
--limit=1 \
--format="value(name)")
gcloud run jobs executions describe $EXECUTION_ID \
--region=REGION \
--project=NEW_PROJECT_ID \
--format="value(status.conditions[0].status,status.conditions[0].message)"
# Check current Job configuration
gcloud run jobs describe JOB_NAME \
--region=REGION \
--project=NEW_PROJECT_ID \
--format="yaml(spec.template.spec.template.spec)"
# Check only VPC configuration
gcloud run jobs describe JOB_NAME \
--region=REGION \
--project=NEW_PROJECT_ID \
--format="yaml(spec.template.metadata.annotations)"
# Check environment variables
gcloud run jobs describe JOB_NAME \
--region=REGION \
--project=NEW_PROJECT_ID \
--format="yaml(spec.template.spec.template.spec.containers[0].env)"