Como se conectar ao Cloud SQL usando o Cloud Functions

Nesta página, você verá informações e exemplos de como se conectar a uma instância do Cloud SQL usando um serviço em execução no Cloud Functions.

O Cloud SQL é um serviço de banco de dados totalmente gerenciado que ajuda você com a configuração, a manutenção, o gerenciamento e a administração dos seus bancos de dados relacionais na nuvem.

O Cloud Functions é uma solução de computação leve usada por desenvolvedores para criar funções autônomas e de finalidade única que respondem a eventos do Cloud sem a necessidade de gerenciar um servidor ou um ambiente de execução.

Configurar uma instância do Cloud SQL

  1. Ative a API Cloud SQL Admin no projeto do qual você está se conectando, caso ainda não tenha feito isso:

    Ative a API

  2. Crie uma instância do Cloud SQL para PostgreSQL.

    Por padrão, o Cloud SQL atribui um endereço IP público a uma nova instância. Você também tem a opção de atribuir um endereço IP particular. Para mais informações sobre as opções de conectividade de ambos, consulte a página Visão geral da conexão.

Como configurar o Cloud Functions

As etapas para configurar o Cloud Functions dependem do tipo de endereço IP atribuído à instância do Cloud SQL.

IP público (padrão)

Para configurar o Cloud Functions para ativar conexões com uma instância do Cloud SQL:

  • Verifique se a instância criada acima tem um endereço IP público. Você pode verificar isso na página Visão geral da sua instância no Console do Google Cloud. Se precisar adicionar um, consulte a página Como configurar o IP público para ver instruções.
  • Receba o INSTANCE_CONNECTION_NAME da instância. Isso pode ser encontrado na página Visão geral da instância no Console do Google Cloud ou executando o seguinte comando: gcloud sql instances describe [INSTANCE_NAME].
  • Verifique se a conta de serviço usada pela função para autenticar chamadas para o Cloud SQL tem os papéis e permissões adequados do Cloud SQL.
    • A conta de serviço do seu serviço precisa de um dos seguintes papéis do IAM:
      • Cloud SQL Client (recomendável)
      • Cloud SQL Editor
      • Cloud SQL Admin
      Também é possível atribuir manualmente as seguintes permissões do IAM:
      • cloudsql.instances.connect
      • cloudsql.instances.get
      Para receber instruções detalhadas sobre como adicionar papéis do IAM a uma conta de serviço, consulte Como conceder papéis a contas de serviço.

    Por padrão, o app autorizará suas conexões usando a conta de serviço do Cloud Functions. A conta de serviço está no formato service-PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com.

    Se a conta de serviço de autorização pertencer a um projeto diferente da instância do Cloud SQL, as permissões da API Cloud SQL Admin e do IAM deverão ser adicionadas aos dois projetos.

IP privado

Um conector de acesso VPC sem servidor processa a comunicação com sua rede VPC. Para se conectar diretamente com IP particular, você precisa:

  1. Verifique se a instância do Cloud SQL criada acima tem um endereço IP particular. Se você precisar adicionar um, consulte a página Como configurar o IP particular para ver instruções.
  2. Crie um conector de acesso VPC sem servidor na mesma rede VPC da sua instância do Cloud SQL.
  3. A menos que você esteja usando a VPC compartilhada, é necessário que um conector esteja no mesmo projeto e na mesma região do recurso que o utiliza, mas o conector pode enviar tráfego para recursos em regiões diferentes.

    O acesso VPC sem servidor é compatível com a comunicação com redes VPC conectadas por meio do Cloud VPN e de peering de rede VPC.

    O acesso VPC sem servidor não é compatível com redes legadas.

  4. Configure o Cloud Functions para usar o conector.
  5. Conecte-se usando o IP privado e a porta 5432 da instância.

Como se conectar ao Cloud SQL

Depois de configurar o Cloud Functions, conecte-se à instância do Cloud SQL. O Cloud Functions fornece um mecanismo que se conecta usando o Cloud SQL Proxy.

IP público (padrão)

IP particular

Como se conectar com TCP

Conecte-se diretamente usando o endereço IP particular e a porta 5432 da instância.

Python

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub.

# Remember - storing secrets in plaintext is potentially unsafe. Consider using
# something like https://cloud.google.com/secret-manager/docs/overview to help keep
# secrets secret.
db_user = os.environ["DB_USER"]
db_pass = os.environ["DB_PASS"]
db_name = os.environ["DB_NAME"]
db_host = os.environ["DB_HOST"]

# Extract host and port from db_host
host_args = db_host.split(":")
db_hostname, db_port = host_args[0], int(host_args[1])

pool = sqlalchemy.create_engine(
    # Equivalent URL:
    # postgres+pg8000://<db_user>:<db_pass>@<db_host>:<db_port>/<db_name>
    sqlalchemy.engine.url.URL(
        drivername="postgres+pg8000",
        username=db_user,  # e.g. "my-database-user"
        password=db_pass,  # e.g. "my-database-password"
        host=db_hostname,  # e.g. "127.0.0.1"
        port=db_port,  # e.g. 5432
        database=db_name  # e.g. "my-database-name"
    ),
    # ... Specify additional properties here.
)

Node.js

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub.

const connectWithTcp = config => {
  // Extract host and port from socket address
  const dbSocketAddr = process.env.DB_HOST.split(':'); // e.g. '127.0.0.1:5432'

  // Establish a connection to the database
  return Knex({
    client: 'pg',
    connection: {
      user: process.env.DB_USER, // e.g. 'my-user'
      password: process.env.DB_PASS, // e.g. 'my-user-password'
      database: process.env.DB_NAME, // e.g. 'my-database'
      host: dbSocketAddr[0], // e.g. '127.0.0.1'
      port: dbSocketAddr[1], // e.g. '5432'
    },
    // ... Specify additional properties here.
    ...config,
  });
};

Go

Para ver esse snippet no contexto de um aplicativo da Web, consulte o README no GitHub.

var (
	dbUser    = mustGetenv("DB_USER")     // e.g. 'my-db-user'
	dbPwd     = mustGetenv("DB_PASS")     // e.g. 'my-db-password'
	dbTcpHost = mustGetenv("DB_TCP_HOST") // e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
	dbPort    = mustGetenv("DB_PORT")     // e.g. '5432'
	dbName    = mustGetenv("DB_NAME")     // e.g. 'my-database'
)

var dbURI string
dbURI = fmt.Sprintf("host=%s user=%s password=%s port=%s database=%s", dbTcpHost, dbUser, dbPwd, dbPort, dbName)

// dbPool is the pool of database connections.
dbPool, err := sql.Open("pgx", dbURI)
if err != nil {
	return nil, fmt.Errorf("sql.Open: %v", err)
}

// ...

return dbPool, nil

Práticas recomendadas e outras informações

É possível usar o Cloud SQL Proxy ao testar seu aplicativo localmente. Acesse o guia de início rápido sobre como usar o proxy para testes locais e veja instruções detalhadas.

Pools de conexões

As conexões com bancos de dados subjacentes podem ser descartadas pelo próprio servidor de banco de dados ou pela infraestrutura subjacente ao Cloud Functions. Recomendamos o uso de uma biblioteca de cliente compatível com pools de conexão que reconectam automaticamente conexões de cliente corrompidas. Além disso, recomendamos o uso de um pool de conexão de escopo global. Com ele, é mais provável que sua função reutilize a mesma conexão para as próximas invocações da função e feche a conexão de maneira natural quando a instância for removida (reduzida automaticamente). Para exemplos mais detalhados sobre como usar pools de conexão, consulte Como gerenciar conexões de banco de dados.

Limites de conexão

O Cloud SQL impõe um limite máximo de conexões simultâneas, e esse limite pode variar dependendo do mecanismo de banco de dados escolhido (consulte a página "Cotas e limites" do Cloud SQL). É recomendável usar uma conexão com o Cloud Functions, mas é importante definir o número máximo de conexões como 1.

Sempre que possível, inicialize um pool de conexões apenas para funções que precisem de acesso ao banco de dados. Alguns pools de conexões criam conexões preventivamente, que podem consumir recursos excessivos e contar nos limites de conexão. Por esse motivo, recomendamos usar a Inicialização lenta para atrasar a criação de um pool de conexões até ser necessário e incluir somente o pool de conexões em funções em que ele é usado.

Para exemplos mais detalhados sobre como limitar o número de conexões de bancos de dados, consulte Como gerenciar conexões de bancos de dados.

Limites de cota da API

O Cloud Functions fornece um mecanismo que se conecta usando o Cloud SQL Proxy, o qual usa a API Cloud SQL Admin. Os limites de cota da API se aplicam ao Cloud SQL Proxy.