<p>I need to connect to Google Cloud SQL from a Kubernetes pod using Go.</p>

<p>I have been following the following guides religiously:
<a href="https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine" rel="nofollow noreferrer">https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine</a>
<a href="https://cloud.google.com/sql/docs/mysql/connect-external-app#go" rel="nofollow noreferrer">https://cloud.google.com/sql/docs/mysql/connect-external-app#go</a></p>

<p>Here is my <strong>Kubernetes deployment yaml</strong> file:</p>

<pre><code>---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-service
  labels:
    app: my-service
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 10%
      maxSurge: 10%
  replicas: 1
  template:
    metadata:
      labels:
        app: my-service
    spec:
      imagePullSecrets:
      - name: regsecret
      containers:
      - name: my-service
        image: my-image
        imagePullPolicy: IfNotPresent
        env:
          - name: DB_INSTANCE
            value: "my-project-id:europe-west1:uk"
          - name: DB_USERNAME
            valueFrom:
              secretKeyRef:
                name: cloudsql-db-credentials
                key: username
          - name: DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: cloudsql-db-credentials
                key: password
      - name: cloudsql-proxy
        image: gcr.io/cloudsql-docker/gce-proxy:1.11
        command: ["/cloud_sql_proxy",
                  "-instances=my-project-id:europe-west1:uk=tcp:3306",
                  "-credential_file=/secrets/cloudsql/credentials.json"]
        volumeMounts:
          - name: cloudsql-instance-credentials
            mountPath: /secrets/cloudsql
            readOnly: true
      volumes:
        - name: cloudsql-instance-credentials
          secret:
            secretName: cloudsql-instance-credentials
</code></pre>

<p>And here is my attempt to connect using <strong>Go</strong>:</p>

<pre><code>import (
    "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/mysql"
    "github.com/spf13/viper"
    "log"
)

func Connect() {
    cfg := mysql.Cfg(
        viper.GetString("DB_INSTANCE"),
        viper.GetString("DB_USERNAME"),
        viper.GetString("DB_PASSWORD"))
    cfg.DBName = "my-db-name"

    db, err := mysql.DialCfg(cfg)
    if err != nil {
        log.Fatalf("Failed to create the Cloud SQL client: %v", err)
    }
}
</code></pre>

<p>Unfortunately, running this code results in:</p>

<pre><code>2018/08/08 15:19:45 Failed to create the Cloud SQL client: ensure that the Cloud SQL API is enabled for your project (https://console.cloud.google.com/flows/enableapi?apiid=sqladmin). Error during createEphemeral for my-project-id:europe-west1:uk: googleapi: Error 403: Insufficient Permission, insufficientPermissions
</code></pre>

<p>I can confirm that the database obviously exists in Cloud SQL, the <strong>Cloud SQL API</strong> is indeed enabled, and that the service account that I used to generate the credentials (as described in the links above) does have the <strong>Cloud SQL Client</strong> role attached to it (I have also tried with Cloud SQL Admin and even project Owner with no success).</p>

<p>What am I missing?</p>

<p><strong>EDIT:</strong></p>

<p>Fixed it by updating my Go code to:</p>

<pre><code>dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s",
    viper.GetString("DB_USERNAME"),
    viper.GetString("DB_PASSWORD"),
    "127.0.0.1:3306",
    "my-db-name")
db, err := sql.Open("mysql", dsn)
if err != nil {
    log.Fatalf("Failed to create the Cloud SQL client: %v", err)
}
</code></pre>

<p>Thanks @DazWilkin for the tip.</p>

<p>I know you've solved your issue already, but wanted to provide another alternative for anyone else reading this thread.</p>

<p>There are 2 ways you can connect to your instance:
1: Through a TCP connection: You have that solution already and <a href="https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine" rel="nofollow noreferrer">this page</a> shows you the details. Since the cloud SQL proxy container runs on the same pod as your app container, your host should point to <code>localhost</code>.
2: Unix socket: </p>

<p>You should also be able to connect through the following code (<a href="https://cloud.google.com/sql/docs/mysql/connect-external-app#go" rel="nofollow noreferrer">details here</a>):</p>

<pre><code>import (
       "database/sql"
        _ "github.com/go-sql-driver/mysql"
)

dsn := fmt.Sprintf("%s:%s@unix(/cloudsql/%s)/%s",
       dbUser,
       dbPassword,
       INSTANCE_CONNECTION_NAME,
       dbName)
db, err := sql.Open("mysql", dsn)
</code></pre>

<p>You may have to remove the <code>=tcp:3306</code> portion from your deployment.yaml file through.</p>
