ローカル環境からCloud SQL(MySQL)への接続

# Cloud SQLの作成

##インスタンスの作成
![スクリーンショット 2020-02-04 9.10.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/049ece15-067a-02c9-65c0-432ca28b355b.png)

詳細オプションでは、「ストレージの自動増量を有効化」と「バックアップを自動化する」のチェックを外します。

##ユーザーの作成

![スクリーンショット 2020-02-04 9.19.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/a06628d9-5a6e-bd56-2e95-7449467b8e62.png)

![スクリーンショット 2020-02-04 9.20.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/6eae6e54-50a8-e529-1f62-65e5ad4c0953.png)

##データベースの作成

![スクリーンショット 2020-02-04 9.21.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/f3f1a395-27d1-580e-26c6-c1e38cb7e8eb.png)

![スクリーンショット 2020-02-04 9.21.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/0d2102f2-dc5b-9e3d-7151-be9235018d56.png)

##テーブルの作成
![スクリーンショット 2020-02-04 9.23.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/92e01afe-4944-37a5-e99a-e4b063d00448.png)

画面下部にCloud Shellの画面が表示されます。
以下のコマンドを入力します。
```
gcloud sql connect [インスタンス名] --user=[ユーザー名]
```
接続が完了すると、以下のパスワード入力画面が表示されます。
![スクリーンショット 2020-02-04 9.31.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/a9a68c32-6bf4-9efb-7601-3c4195441a4e.png)
パスワードを入力し、接続が完了すると、以下の画面が表示されます。
![スクリーンショット 2020-02-04 9.31.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/3b729c10-ce0e-8845-e374-cfdec6ad4d2c.png)


利用するデータベースを切り替えます。
```
use mydb
```
テスト用のテーブルとデータを作成します。

```
CREATE TABLE users (ID INT NOT NULL AUTO_INCREMENT, Name VARCHAR(255) NOT NULL, date DATETIME, PRIMARY KEY(ID));
```

```
INSERT INTO users (Name, date) values ('鈴木', '2020-02-03 12:00:00');
INSERT INTO users (Name, date) values ('田中', '2017-02-03 13:00:00');
```

##サービスアカウント作成

[IAMと管理]-[サービスアカウント]を選択し、サービスアカウントを作成します。

![スクリーンショット 2020-02-04 10.07.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/4c0aeb2b-fa9a-0def-87e2-6bceeaad4678.png)

権限は、以下の通りです。
・Cloud SQL クライアント
・Cloud SQL 編集者
![スクリーンショット 2020-02-04 10.08.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/9c69632e-2e67-428b-86f9-d72bb7a930a0.png)

キーを作成します。
キーのタイプが[JSON]になっていることを確認してください。
![スクリーンショット 2020-02-04 10.08.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/90f2b0c0-5c1a-672e-575b-a0d0a4a1aaf2.png)

![スクリーンショット 2020-02-04 10.08.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/7a4fe1a0-0cf0-7576-8e5d-d370071d2b39.png)


#ローカル環境の作成

##環境変数の設定
GOOGLE_APPLICATION_CREDENTIALS環境変数には、作成したサービスアカウントの秘密鍵へのパスを設定します。

```
export GOOGLE_APPLICATION_CREDENTIALS=xxxxx.json
```

##ソース

```go:main.go
package main

import (
    "log"
    "fmt"
    "time"
    cloudsqlproxy "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/mysql"
    "github.com/go-sql-driver/mysql"
)

func main() {
    if err := showRecords("インスタンス名", "データベース", "ユーザ名", "パスワード"); err != nil {
        log.Fatal(err)
    }
}

func showRecords(dbAddress, dbName, dbUser, dbPassword string) error {
    // 接続するだけなら以下のコードになります。
    // db, err := cloudsqlproxy.DialPassword(dbAddress, dbUser, dbPassword)

    // 詳細に設定したい場合は以下のコードになります。
    db, err := cloudsqlproxy.DialCfg(&mysql.Config{
        Addr:      dbAddress,  // インスタンス接続名
        DBName:    dbName,     // データベース名
        User:      dbUser,     // ユーザ名
        Passwd:    dbPassword, // ユーザパスワード
        Net:       "cloudsql", // Cloud SQL Proxy で接続する場合は cloudsql 固定です
        ParseTime: true,       // DATE/DATETIME 型を time.Time へパースする
        TLSConfig: "",         // TLSConfig は空文字を設定しなければなりません
        AllowNativePasswords: true, // <- これがないと、「this user requires mysql native password authentication」エラー
    })
    if err != nil {
        return err
    }
    defer db.Close()

    rows, err := db.Query("SELECT * FROM users")
    if err != nil {
        return err
    }
    defer rows.Close()

    for rows.Next() {
        var Name string
        var date time.Time
        var ID int64
        if err := rows.Scan(&ID, &Name, &date); err != nil {
            return err
        }
        fmt.Printf("%d\t%s\t%s\n", ID, Name, date.Format(time.RFC3339))
    }

    return nil
}
```

###　インスタンス名

インスタンス名は、以下の[インスタンス接続名]を設定します。
![スクリーンショット 2020-02-04 10.40.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/58107ce7-5d07-ed57-5dec-5e5b4f92d94d.png)

#参考
[Cloud SQL Proxy を Golang のパッケージとして使用する](https://qiita.com/hirsim/items/88325da17cd333ee324e)
[golang mysql driverで `this user requires mysql native password authentication.](https://qiita.com/ushio_s/items/ab64e7e9222bb5a67a11)
[GCPのCloud Shellを使ってCloud SQLインスタンスに接続する方法](https://tonari-it.com/gcp-cloud-shell-gcloud-sql/)