LaravelからGCPのCloudSQLに接続できるようにする

AppEngineにlaravelアプリケーションをデプロイしても、DB接続とか面倒なのでメモ。

CloudSqlにローカルから接続できるようにする

  • cloud_sql_proxyダウンロード
curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
  • プロキシを実行可能に
chmod +x cloud_sql_proxy
  • 秘密鍵を取得する
Google Cloud Platform Console の Cloud SQL の [サービス アカウント] ページに移動します。
[サービス アカウント] ページに移動

必要に応じて、Cloud SQL インスタンスを含むプロジェクトを選択します。
[サービス アカウントを作成] をクリックします。
[サービス アカウントを作成] ダイアログで、わかりやすいサービス アカウント名を指定します。
[役割] で、次のいずれかの役割を選択します。
[Cloud SQL] > [Cloud SQL クライアント]
[Cloud SQL] > [Cloud SQL 編集者]
[Cloud SQL] > [Cloud SQL 管理者]
あるいは、[プロジェクト] > [編集者] の順に選択して、編集者の基本的な役割を使用できますが、編集者の役割には Google Cloud Platform 全体の権限が含まれます。

これらの役割が表示されない場合、Google Cloud Platform ユーザーに resourcemanager.projects.setIamPolicy 権限がない可能性があります。権限を確認するには、Google Cloud Platform Console の [IAM] ページにアクセスし、自分のユーザー ID を検索します。

必要に応じて [サービス アカウントの ID] を一意のわかりやすい値に変更して、後でこのサービス アカウントを簡単に見つけられるようにします。
[新しい秘密鍵の提供] をクリックします。
デフォルトのキータイプは JSON であり、この値を使用するのが適切です。
[作成] をクリックします。
秘密鍵ファイルがマシンにダウンロードされます。秘密鍵ファイルは、別の場所に移動できます。安全な場所に鍵ファイルを保管してください。

接続コマンド実行

<INSTANCE_CONNECTION_NAME>はSQLのインスタンスIDを指定

./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306 \ -credential_file=<PATH_TO_KEY_FILE> &

だが、こんな感じのエラーが出る。

couldn't connect to "aaaaaaaaaaa": ensure that the account has access to "aaaaaaaaaaaa" (and make sure there's no typo in that name). Error during createEphemeral for aaaaaaaaaa: googleapi: Error 403: Access Not Configured. Cloud SQL Admin API has not been used in project aaaaaaaaa before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/sqladmin.googleapis.com/overview?project=aaaaaaaaaa then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry., accessNotConfigured

Cloud SQL Admin API has not been usedとか書かれているから、これを有効にすればいけるはず。「APIとサービス」->「ライブラリ」から該当のAPIを探そう。

f:id:utr066:20190113025254p:plain

真ん中のやつだね。これを有効化して接続コマンドを実行すればいけるはず。

DBの中身を参照できるようにする

composer.jsonに以下を記述。

"post-install-cmd": [
        "chmod -R 755 bootstrap\/cache",
        "php artisan cache:clear"
    ]

で、migrateするには必要な情報がありますね。そうです、DBの接続情報です。localでは、だいたいenvファイルにDB_HOSTなんかの情報を指定していると思うけど、AppEngineの場合はそれらの環境変数をapp.yamlに記述する。

env_variables:
  # Put production environment variables here.
  # DB接続情報を追記
  DB_CONNECTION: mysql
  DB_HOST: localhost
  DB_PORT: 3306
  DB_DATABASE: GCPのsqlで作ったDB名
  DB_USERNAME: 作成時に作ったユーザー名
  DB_PASSWORD: 作成時に作ったパスワード名
  DB_SOCKET: /cloudsql/YOUR_STAGING_PROJECT_ID:asia-northeast1:YOUR_CLOUDSQL_INSTANCE_ID
beta_settings:
  cloud_sql_instances: YOUR_STAGING_PROJECT_ID:asia-northeast1:YOUR_CLOUDSQL_INSTANCE_ID

migrateする

AppEngine上ではphp artisan migrate実行できないようなので、ローカルからやるしかない・・・

データベース作成

migrateしようと思っても、データベースが存在しないなら意味がない。GCP上からデータベースを作成。 f:id:utr066:20190113053202p:plain

migrationをローカルから実行

ENVの値をCloudSqlを見にいくように書き換えてからphp artisan migrateを実行しよう。この時には、上の方で書いた接続コマンドは実行されている状態にしておくように。

DB_HOST=127.0.0.1
DB_PORT= PORT名
DB_DATABASE=DB名
DB_USERNAME=ユーザー名
DB_PASSWORD=パスワード

これでCloudSqlの方にもmigrateされたデータが入るはず。