0

I am simply not able to establish a connection to my Cloud SQL instance (PostreSQL). For deployment, I have created a cloudbuild.yamlbut no matter what I try, I'm not able to connect.

For now, I am just creating a .env during a build step. I am aware that this is not safe. I'm intending to fix this later on.

steps:
  - name: 'gcr.io/cloud-builders/docker'
    entrypoint: 'bash'
    args:
      - '-c'
      - |
        echo "ENVIRONMENT=development" > .env
        echo "DB_HOST=12.34.56.78 >> .env
        echo "DB_NAME=my-database-dev" >> .env
        echo "DB_USERNAME=postgres" >> .env
        echo "DB_PASSWORD=password" >> .env
        echo "DB_DIALECT=postgres" >> .env
        echo "CLOUD_SQL_INSTANCE="$_CLOUD_SQL_INSTANCE >> .env

  # Step to install dependencies
  - name: 'gcr.io/cloud-builders/npm'
    args: [ 'install' ]
  # Step to apply Sequelize migrations
  - name: 'gcr.io/cloud-builders/npm'
    args: [ 'run', 'db:migrate' ]

As I am calling gcloud builds submit . I am getting to the following error-response. Note, that I am doing this with my own account, not a Service Account. I am owner of the project but I added Cloud SQL Admin for good measure to my roles for now.

{
  "error": {
    "code": 401,
    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "errors": [
      {
        "message": "Login Required.",
        "domain": "global",
        "reason": "required",
        "location": "Authorization",
        "locationType": "header"
      }
    ],
    "status": "UNAUTHENTICATED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "CREDENTIALS_MISSING",
        "domain": "googleapis.com",
        "metadata": {
          "method": "google.cloud.sql.v1beta4.SqlConnectService.GetConnectSettings",
          "service": "sqladmin.googleapis.com"
        }
      }
    ]
  }
}

I don't understand why I get this error and how to fix this.

Additionally, I'd like to highlight that I am not available to connect to the database using psql. Perhaps, this is expected, but in trying to get any connection going, I tried to rune psql -h postgresql://user:password@public-ip/database-name but only got a timeout from that.

Last but not least, since I am using Sequelize, this is how I am initializing it:

const connector = new Connector();
const clientOpts = connector.getOptions({
  instanceConnectionName: process.env.CLOUD_SQL_INSTANCE,
  ipType: IpAddressTypes.PUBLIC,
  authType: process.env.DB_PASSWORD ? AuthTypes.PASSWORD : AuthTypes.IAM,
});
dbConfig = {
  username: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  host: process.env.DB_HOST,
  database: process.env.DB_NAME,
  dialect: process.env.DB_DIALECT,
  dialectOptions: clientOpts,
};
export const sequelize = new Sequelize({
  ...dbConfig,
  models: [/* ... */],
});

// Test connection
try {
  console.log('[sequelize.ts] Testing connection ..');
  sequelize
    .authenticate()
    .catch((err) => console.error('Unable to connect to the database:', err))
    .then();
} catch (err) {
  console.error('Unable to connect to the database:', err);
}

In general, I am able to connect locally via the gcloud sql command:

$ gcloud sql connect myproject-postgres-dev --user=postgres

It's not clear to me whether I am doing something wrong here in general, or whether there's an issue with Sequelize.

Can somebody please guide me though this?

2
  • Have you tried the solution from this thread? Also check this link. Commented Feb 19, 2024 at 6:34
  • 1
    @RoopaM Thank you, but I was able to solve the issue. Didn't have time to post an answer yet. The problem was/is that connector.getOptions() returns a promise which I had to await for. I assumed that this will be done for me but as it turns out, the constructor is fully synchronous. As such, I converted my entire project to use ESM s.t. I can use top-level await. With that the problem was resolved. :) Commented Feb 19, 2024 at 9:36

1 Answer 1

0

When an application connects to Cloud SQL using the Cloud SQL Connector, it needs two sets of credentials:

  • The Postgresql database username and password. Your code appears to handle this correctly.
  • The Google Cloud Application Default credentials. This is usually configured using Google Cloud IAM.

Since this code is running in a Cloud Build job, you need to grant the SQL Client role (roles/cloudsql.client) to the Cloud Build service account. Configure Access for the Cloud Build Service Account help article describes how to do this in detail.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.