본문 바로가기
개발

git action에서 Cloud SQL 인증 프록시로 db migration 하기

by 박연호의 개발 블로그 2025. 2. 13.

저희 팀에서는 prisma orm migration을 사용하기 때문에 예시에 사용되는 코드는 prisma 기반으로 작성 됩니다. 

 

기존 저희 서버의 CI/CD과정에서 docker image를 만들어 배포하고, db migration 하는 과정은 아래와 같았습니다.

 

- develop/staging/production push

- git action 실행

- git action에서 gcp compute engine에 접속

- develop/staging/production 브랜치에서 git pull

- docker build(Dockerfile 내부에 db migration 코드 존재)

- docker container

 

저희 팀에서는 prisma orm을 사용하고 있었고, prisma 자체적으로 migration하는 기능이 포함되어 있어 package.json에 명령어를 추가하여 migration하도록 하였습니다.

 

하지만 위 방법에서, docker build 과정에 db migration이 포함되어 있는것이 적절하지 못하다고 생각하였고, 이 둘을 분리하고 싶었습니다. 또 시기적으로, staging 환경을 gke로 전환하는 과정에서 docker build하는 과정을 git action에서 해야 했습니다.

 

이 경우 docker build 과정에 db migration이 있으니 결국 git action 서버에서 db migration을 해야 하는데, 그렇다면 지금의 구조대로면 git action의 ip를 gcp sql의 화이트리스트 ip에 추가해줘야 하는 과정이 포함되어야 합니다. 저는 이렇게 매번 gcp sql에 ip를 등록해줘야 하는 과정이 불필요하고 생각했습니다.

 

이렇게 매번 gcp sql에 git action ip를 등록하는 것보단, Cloud SQL을 통해 단발성으로 연결할 수 있습니다.


Cloud SQL 인증 프록시

 

Cloud SQL은 서비스 계정 Key와 IAM 권한을 사용하여 Cloud SQL에 접근할 수 있으며, 로컬 환경(git action)에서 로컬 클라이언트를 실행하여 작동합니다. 

 

로컬 환경에 맞게 Cloud SQL 인증 프록시를 다운로드 받고, 언어 및 환경에 맞게 TCP 소켓, Cloud SQL 인증 프록시 Docker 이미지를 사용하여 인증 프록시를 사용할 수 있습니다.

 

특히 TCP 연결의 경우 Cloud SQL 인증 프록시는 기본적으로 localhost(127.0.0.1)에 리슨합니다. remote db와의 통신은 인증 프록시를 매개로 연결되기 때문에 로컬에 설치된 인증 프록시로 연결되어야 합니다. 

 

1. 서비스 계정 생성

먼저 git action 인증 프록시에서 사용할 서비스 계정을 만들어 줘야 합니다. 내가 누구고 어떤 기능을 사용할 지 확인해야 하기 때문입니다.
해당 서비스 계정이 인증 프록시 작업을 할 수 있도록 Cloud SQL 권한이 필요합니다. 만약 기존에 사용중인 서비스 계정을 사용한다면, 아래 권한을 추가해줘야 합니다.

 

아래 처럼 서비스 계정을 만들어 줍니다. 

 

만든 서비스 계정을 코드 레벨에서 사용하기 위해서는 key를 발급받아야 합니다. 생성된 키는 JSON 형태로, 이후에 git action에서 인증 프록시에 연결하기 위한 사용자 인증 정보로 사용됩니다.

 

2. secret 작성

추가해야 하는건 2가지 입니다.

1. 서비스 계정 키(아까 다운로드 받은 JSON 파일) -> SQL_PROXY_KEY

JSON을 그대로 복붙하면 됩니다.

 

 

2. 연결한 DB의 계정 정보 -> SQL_URL

인증 프로시는 TCP 소켓으로 연결하는 경우


프록시 인증 방법에서는 공개 IP와 id/pw로 접근한다면, 인증 프록시 방법의 경우 Cloud SQL Proxy를 통해서 GCP SQL와 연결이 됩니다. 해당 어플리케이션에서 연결해야 할 db instance 정보는 id/pw는 동일하지만 ip를 127.0.0.1이어야 합니다.

 

예를 들어, 다음과 같습니다. 

mysql://root:dusgh4314@127.0.0.1:3306/test

 

실제 연결할 remote db는 아래 인증 프록시를 실행할 때, 전달합니다.

 

3. git action 작성

 

git action의 전체 흐름은 아래와 같습니다. 

 

1. 앞서 생성한 서비스 계정을 action server에 파일로 생성

2. Cloud SQL Proxy 바이너리 다운로드

3. cloud_sql_proxy 실행

4. db migration

 

 proxy에서 사용할 인증 서비스 계정 키 가져온 다음에, proxy 하는 파일 다운로드 받아서 실행하고 db migration.

뭔가 게임하기 위해 게임 다운로드받고 로그인하고 게임실행하는 것 같네요.

name: sql proxy

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code from Develop Staging
        uses: actions/checkout@v4

      - name: load secret and download sql proxy
        run: |
          echo '${{ secrets.SQL_PROXY_KEY }}' > $HOME/gcp-key.json
          echo "GOOGLE_APPLICATION_CREDENTIALS=$HOME/gcp-key.json" >> $GITHUB_ENV
          wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
          chmod +x cloud_sql_proxy

      - name: db migration
        env:
          DATABASE_URL: ${{ secrets.SQL_URL }}
        run: |
          ./cloud_sql_proxy -instances=yhparkkk:asia-northeast3:dusgh4314=tcp:3306 &
          npm install prisma
          npx prisma migrate deploy
          exit 0;

 

하나씩 뜯어 보겠습니다.

 

echo '${{ secrets.SQL_PROXY_KEY }}' > $HOME/gcpkey.json

echo "GOOGLE_APPLICATION_CREDENTIALS=$HOME/gcp-key.json" >> $GITHUB_ENV

-> 서비스 계정키(SQL_PROXY_KEY)를 가져와서 $HOME/gcpkey.json에 저장한 다음에, 그 경로를 GOOGLE_APPLICATION_CREDENTIALS에 넣어 환경변수로 만듦.

 

환경변수를 만드는 이유는 sql proxy를 실행하기 위해(./cloud_sql_proxy) GOOGLE_APPLICATION_CREDENTIALS라는 환경변수에 사용자 인증 정보 파일(서비스 계정 키 JSON)의 "경로"값이 있어야 함.

 

 

wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy 

chmod +x cloud_sql_proxy

-> Cloud SQL 인증 프록시를 다운로드 받은 다음에, 실행할 수 있도록 권한을 변경합니다.

 

 

 

env:

     DATABASE_URL: ${{ secrets.SQL_URL }}

run: | ./cloud_sql_proxy -instances=yhparkkk:asia-northeast3:dusgh4314=tcp:3306 &

npm install prisma

npx prisma migrate deploy

exit 0;

-> DATABASE_URL은 prisma orm에서 사용할 db 계정 정보입니다.

Cloud SQL 인증 프록시를 실행 할때는 실제로 연결한 remote db 인스턴스 명이 필요합니다. 그리고 프록시가 remote db에 TCP로 연결하고, mysql 기본포트 3306을 지정해줍니다.

 

&을 지정하여, 별도의 프로세스에서 Cloud SQL 인증 프록시를 실행하도록 합니다. &를 입력하지 않으면 이후의 명령어(npm install prisma)가 실행되지 않습니다.