使用 IAM 数据库身份验证管理用户

本页面介绍了如何向使用 IAM 数据库身份验证的 Cloud SQL 实例添加和管理用户、服务账号和群组。

如需详细了解 IAM 集成,请参阅 IAM 身份验证

准备工作

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Install the Google Cloud CLI.
  5. To initialize the gcloud CLI, run the following command:

    gcloud init
  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  7. Make sure that billing is enabled for your Google Cloud project.

  8. Install the Google Cloud CLI.
  9. To initialize the gcloud CLI, run the following command:

    gcloud init
  10. 确保您的用户账号具有 Cloud SQL Admin 角色。

    转到 IAM 页面

  11. 在 Cloud SQL 实例上启用 IAM 数据库身份验证
  12. 向 IAM 主账号(例如 IAM 用户服务账号群组)分配必要的 cloudsql.instanceUser IAM 角色,以便登录 Cloud SQL 实例。
    • 如果您要将单个用户或单个服务账号添加到 Cloud SQL 实例,则需要单独向每个用户和服务账号分配 IAM 角色。
    • 如果您要添加群组,则需要向群组分配 IAM 角色,因为群组成员会自动继承与 IAM 角色关联的 IAM 权限。如需详细了解如何在 Cloud Identity 中创建群组,请参阅在 Google Cloud 控制台中创建和管理 Google 群组
    • 您可以使用 Google Cloud 控制台的 IAM 页面、gcloud CLI、Terraform 或 Cloud SQL Admin API 授予针对包含 Cloud SQL 实例的项目的角色。如需了解详情,请参阅向用户、服务账号或群组添加 IAM 政策绑定
  13. 如果您使用的是服务账号,请确保您已为需要访问项目中的数据库的每个服务添加了服务账号
  14. 如需详细了解如何创建服务账号,请参阅创建服务账号

向用户、服务账号或群组添加 IAM 政策绑定

在给定项目 ID 和绑定的情况下,此过程将政策绑定添加到特定项目的 IAM 政策。绑定命令由成员、角色和可选条件组成。

数据库用户名必须是 IAM 用户的电子邮件地址,例如 example-user@example.com。该用户名必须全部为小写并使用英文引号,因为它包含特殊字符(@.)。

控制台

  1. 在 Google Cloud 控制台中,转到 IAM 页面。

    转到 IAM

  2. 点击添加
  3. 新成员中,输入电子邮件地址。您可以将单个用户、服务账号或群组添加为成员,但每个项目必须至少有一个主账号作为成员。
  4. 角色中,前往 Cloud SQL,然后选择 Cloud SQL Instance User
  5. 可选:如果您要使用 Cloud SQL Auth 代理或 Cloud SQL 语言连接器进行连接,请同时选择 Cloud SQL Client
  6. 点击保存

gcloud

运行带有 --role=roles/cloudsql.instanceUser 标志的 gcloud projects add-iam-policy-binding

向用户账号添加政策绑定

替换以下内容:

  • PROJECT_ID:您要授权用户使用的项目的 ID。
  • USERNAME:用户的电子邮件地址。
  gcloud projects add-iam-policy-binding PROJECT_ID \
    --member=user:USERNAME \
    --role=roles/cloudsql.instanceUser
  

如果您要使用 Cloud SQL Auth 代理或 Cloud SQL 语言连接器进行连接,请使用 --role=roles/cloudsql.client 标志再次运行 gcloud projects add-iam-policy-binding

向服务账号添加政策绑定

替换以下内容:

  • PROJECT_ID:您要授权用户使用的项目的 ID。
  • SERVICE_ACCT:服务账号的电子邮件地址。
  gcloud projects add-iam-policy-binding PROJECT_ID \
    --member=serviceAccount:SERVICE_ACCT \
    --role=roles/cloudsql.instanceUser
  

如果您要使用 Cloud SQL Auth 代理或 Cloud SQL 语言连接器进行连接,请使用 --role=roles/cloudsql.client 标志再次运行 gcloud projects add-iam-policy-binding

向 Cloud Identity 群组添加政策绑定

替换以下内容:

  • PROJECT_ID:您要授权群组成员使用的项目的 ID。
  • GROUP_EMAIL_ADDRESS:群组的电子邮件地址。例如 example-group@example.com
  gcloud projects add-iam-policy-binding PROJECT_ID \
    --member=group:GROUP_EMAIL_ADDRESS \
    --role=roles/cloudsql.instanceUser
   

所指定群组的所有成员都将获得 Cloud SQL Instance User 角色,并且可以登录此项目中的实例。

如果您要使用 Cloud SQL Auth 代理或 Cloud SQL 语言连接器进行连接,请使用 --role=roles/cloudsql.client 标志再次运行 gcloud projects add-iam-policy-binding

Terraform

如需向 IAM 用户和服务账号添加所需的政策绑定,请使用 Terraform 资源

data "google_project" "project" {
}

resource "google_project_iam_binding" "cloud_sql_user" {
  project = data.google_project.project.project_id
  role    = "roles/cloudsql.instanceUser"
  members = [
    "user:test-user@example.com",
    "serviceAccount:${google_service_account.default.email}"
  ]
}

resource "google_project_iam_binding" "cloud_sql_client" {
  project = data.google_project.project.project_id
  role    = "roles/cloudsql.client"
  members = [
    "user:test-user@example.com",
    "serviceAccount:${google_service_account.default.email}"
  ]
}

应用更改

如需在 Google Cloud 项目中应用 Terraform 配置,请完成以下部分中的步骤。

准备 Cloud Shell

  1. 启动 Cloud Shell
  2. 设置要在其中应用 Terraform 配置的默认 Google Cloud 项目。

    您只需为每个项目运行一次以下命令,即可在任何目录中运行它。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    如果您在 Terraform 配置文件中设置显式值,则环境变量会被替换。

准备目录

每个 Terraform 配置文件都必须有自己的目录(也称为“根模块”)。

  1. Cloud Shell 中,创建一个目录,并在该目录中创建一个新文件。文件名必须具有 .tf 扩展名,例如 main.tf。在本教程中,该文件称为 main.tf
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. 如果您按照教程进行操作,可以在每个部分或步骤中复制示例代码。

    将示例代码复制到新创建的 main.tf 中。

    (可选)从 GitHub 中复制代码。如果端到端解决方案包含 Terraform 代码段,则建议这样做。

  3. 查看和修改要应用到您的环境的示例参数。
  4. 保存更改。
  5. 初始化 Terraform。您只需为每个目录执行一次此操作。
    terraform init

    (可选)如需使用最新的 Google 提供程序版本,请添加 -upgrade 选项:

    terraform init -upgrade

应用更改

  1. 查看配置并验证 Terraform 将创建或更新的资源是否符合您的预期:
    terraform plan

    根据需要更正配置。

  2. 通过运行以下命令并在提示符处输入 yes 来应用 Terraform 配置:
    terraform apply

    等待 Terraform 显示“应用完成!”消息。

  3. 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 Terraform 已创建或更新它们。

删除更改

如需删除更改,请执行以下操作:

  1. 如需停用删除防护,请在 Terraform 配置文件中将 deletion_protection 参数设置为 false
    deletion_protection =  "false"
  2. 运行以下命令并在提示符处输入 yes,以应用更新后的 Terraform 配置:
    terraform apply
  1. 通过运行以下命令并在提示符处输入 yes,移除之前使用 Terraform 配置应用的资源:

    terraform destroy

Terraform

如需向 IAM 用户和服务账号添加所需的政策绑定,请使用 Terraform 资源

data "google_project" "project" {
}

resource "google_project_iam_binding" "cloud_sql_user" {
  project = data.google_project.project.project_id
  role    = "roles/cloudsql.instanceUser"
  members = [
    "group:example-group@example.com"
  ]
}

应用更改

如需在 Google Cloud 项目中应用 Terraform 配置,请完成以下部分中的步骤。

准备 Cloud Shell

  1. 启动 Cloud Shell
  2. 设置要在其中应用 Terraform 配置的默认 Google Cloud 项目。

    您只需为每个项目运行一次以下命令,即可在任何目录中运行它。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    如果您在 Terraform 配置文件中设置显式值,则环境变量会被替换。

准备目录

每个 Terraform 配置文件都必须有自己的目录(也称为“根模块”)。

  1. Cloud Shell 中,创建一个目录,并在该目录中创建一个新文件。文件名必须具有 .tf 扩展名,例如 main.tf。在本教程中,该文件称为 main.tf
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. 如果您按照教程进行操作,可以在每个部分或步骤中复制示例代码。

    将示例代码复制到新创建的 main.tf 中。

    (可选)从 GitHub 中复制代码。如果端到端解决方案包含 Terraform 代码段,则建议这样做。

  3. 查看和修改要应用到您的环境的示例参数。
  4. 保存更改。
  5. 初始化 Terraform。您只需为每个目录执行一次此操作。
    terraform init

    (可选)如需使用最新的 Google 提供程序版本,请添加 -upgrade 选项:

    terraform init -upgrade

应用更改

  1. 查看配置并验证 Terraform 将创建或更新的资源是否符合您的预期:
    terraform plan

    根据需要更正配置。

  2. 通过运行以下命令并在提示符处输入 yes 来应用 Terraform 配置:
    terraform apply

    等待 Terraform 显示“应用完成!”消息。

  3. 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 Terraform 已创建或更新它们。

删除更改

如需删除更改,请执行以下操作:

  1. 如需停用删除防护,请在 Terraform 配置文件中将 deletion_protection 参数设置为 false
    deletion_protection =  "false"
  2. 运行以下命令并在提示符处输入 yes,以应用更新后的 Terraform 配置:
    terraform apply
  1. 通过运行以下命令并在提示符处输入 yes,移除之前使用 Terraform 配置应用的资源:

    terraform destroy

REST

通过修改 get-iam-policy 命令返回的 JSON 或 YAML 绑定政策,将 cloudsql.instanceUsercloudsql.client 角色授予两种类型的账号。请注意,此政策更改在设置更新后的政策后才会生效。

    {
      "role": "roles/cloudsql.instanceUser",
      "members": [
                   "user:example-user@example.com"
                   "serviceAccount:service1@sql.iam.gserviceaccount.com"
                   "group:example-group@example.com"
      ]
    }
    {
      "role": "roles/cloudsql.client",
      "members": [
                   "user:example-user@example.com"
                   "serviceAccount:service1@sql.iam.gserviceaccount.com"
      ]
    }

将单个 IAM 用户或服务账号添加到 Cloud SQL 实例

您必须为要添加到 Cloud SQL 实例的每个 IAM 用户或服务账号创建新的用户账号,才能访问数据库。如果您要添加 IAM 群组,则无需为该群组的每个成员创建用户账号。

数据库用户名必须是 IAM 用户的电子邮件地址,且必须全部为小写。例如 example-user@example.com

使用 REST 命令时,用户名必须使用英文引号,因为它包含特殊字符(@.)。服务账号使用 service-account-name@project-id.iam.gserviceaccount.com 格式。

如需添加单个 IAM 用户或服务账号,请添加新的用户账号并选择 IAM 作为身份验证方法:

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 从 SQL 导航菜单中选择用户
  4. 点击添加用户账号。系统会打开将用户账号添加到实例 instance_name 标签页。
  5. 点击 Cloud IAM 单选按钮。
  6. 主账号字段中添加要添加的用户或服务账号的电子邮件地址。
  7. 点击添加。该用户或服务账号现在位于用户账号列表中。
  8. 如果用户在创建用户账号后未被分配 cloudsql.instanceUser IAM 角色,则用户名旁边会显示一个 三角形 图标。

    如需为用户授予登录权限,请点击该图标,然后选择添加 IAM 角色。如果该图标不再显示,则表示为用户账号分配了可授予登录权限的 IAM 角色。

gcloud

创建用户账号

使用电子邮件地址(如 example-user@example.com)来标识用户。

替换以下内容:

  • USERNAME:用户的电子邮件地址。
  • INSTANCE_NAME:您要授权用户访问的实例的名称。
gcloud sql users create USERNAME \
--instance=INSTANCE_NAME \
--type=cloud_iam_user

创建服务账号

替换以下内容:

  • SERVICE_ACCT:服务账号的电子邮件地址。
  • INSTANCE_NAME:您要授权服务账号访问的实例的名称。
gcloud sql users create SERVICE_ACCT \
--instance=INSTANCE_NAME \
--type=cloud_iam_service_account

Terraform

如需在启用了 IAM 数据库身份验证的实例上添加 IAM 用户和服务账号,请使用 Terraform 资源

resource "google_sql_database_instance" "default" {
  name             = "postgres-db-auth-instance-name-test"
  region           = "us-west4"
  database_version = "POSTGRES_14"
  settings {
    tier = "db-custom-2-7680"
    database_flags {
      name  = "cloudsql.iam_authentication"
      value = "on"
    }
  }
  # set `deletion_protection` to true, will ensure that one cannot accidentally
  # delete this instance by use of Terraform whereas
  # `deletion_protection_enabled` flag protects this instance at the GCP level.
  deletion_protection = false
}

# Specify the email address of the IAM user to add to the instance
# This resource does not create a new IAM user account; this account must
# already exist

resource "google_sql_user" "iam_user" {
  name     = "test-user@example.com"
  instance = google_sql_database_instance.default.name
  type     = "CLOUD_IAM_USER"
}

# Specify the email address of the IAM service account to add to the instance
# This resource does not create a new IAM service account; this service account
# must already exist

# Create a new IAM service account

resource "google_service_account" "default" {
  account_id   = "cloud-sql-postgres-sa"
  display_name = "Cloud SQL for Postgres Service Account"
}

resource "google_sql_user" "iam_service_account_user" {
  # Note: for PostgreSQL only, Google Cloud requires that you omit the
  # ".gserviceaccount.com" suffix
  # from the service account email due to length limits on database usernames.
  name     = trimsuffix(google_service_account.default.email, ".gserviceaccount.com")
  instance = google_sql_database_instance.default.name
  type     = "CLOUD_IAM_SERVICE_ACCOUNT"
}

应用更改

如需在 Google Cloud 项目中应用 Terraform 配置,请完成以下部分中的步骤。

准备 Cloud Shell

  1. 启动 Cloud Shell
  2. 设置要在其中应用 Terraform 配置的默认 Google Cloud 项目。

    您只需为每个项目运行一次以下命令,即可在任何目录中运行它。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    如果您在 Terraform 配置文件中设置显式值,则环境变量会被替换。

准备目录

每个 Terraform 配置文件都必须有自己的目录(也称为“根模块”)。

  1. Cloud Shell 中,创建一个目录,并在该目录中创建一个新文件。文件名必须具有 .tf 扩展名,例如 main.tf。在本教程中,该文件称为 main.tf
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. 如果您按照教程进行操作,可以在每个部分或步骤中复制示例代码。

    将示例代码复制到新创建的 main.tf 中。

    (可选)从 GitHub 中复制代码。如果端到端解决方案包含 Terraform 代码段,则建议这样做。

  3. 查看和修改要应用到您的环境的示例参数。
  4. 保存更改。
  5. 初始化 Terraform。您只需为每个目录执行一次此操作。
    terraform init

    (可选)如需使用最新的 Google 提供程序版本,请添加 -upgrade 选项:

    terraform init -upgrade

应用更改

  1. 查看配置并验证 Terraform 将创建或更新的资源是否符合您的预期:
    terraform plan

    根据需要更正配置。

  2. 通过运行以下命令并在提示符处输入 yes 来应用 Terraform 配置:
    terraform apply

    等待 Terraform 显示“应用完成!”消息。

  3. 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 Terraform 已创建或更新它们。

删除更改

如需删除更改,请执行以下操作:

  1. 如需停用删除防护,请在 Terraform 配置文件中将 deletion_protection 参数设置为 false
    deletion_protection =  "false"
  2. 运行以下命令并在提示符处输入 yes,以应用更新后的 Terraform 配置:
    terraform apply
  1. 运行以下命令并在提示符处输入 yes,以移除之前使用 Terraform 配置应用的资源:

    terraform destroy

REST v1

创建用户账号

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:项目 ID
  • INSTANCE_ID:您要向其添加用户的实例的 ID
  • USERNAME:用户的电子邮件地址

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID/users

请求 JSON 正文:

{
  "name": "USERNAME",
  "type": "CLOUD_IAM_USER"
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-02-07T22:44:16.656Z",
  "startTime": "2020-02-07T22:44:16.686Z",
  "endTime": "2020-02-07T22:44:20.437Z",
  "operationType": "CREATE_USER",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}

创建服务账号

在使用任何请求数据之前,请先进行以下替换:

  • SERVICE_ACCT:服务账号电子邮件地址
  • PROJECT_ID:项目 ID
  • INSTANCE_ID:您要向其添加服务账号的实例的 ID

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID/users

请求 JSON 正文:

{
    "name": "SERVICE_ACCT",
    "type": "CLOUD_IAM_SERVICE_ACCOUNT"
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
"kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-11-20T04:08:00.211Z",
  "startTime": "2020-11-20T04:08:00.240Z",
  "endTime": "2020-11-20T04:08:02.003Z",
  "operationType": "CREATE_USER",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}

REST v1beta4

创建用户账号

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:项目 ID
  • INSTANCE_ID:您要向其添加用户的实例的 ID
  • USERNAME:用户的电子邮件地址

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID/users

请求 JSON 正文:

{
  "name": "USERNAME",
  "type": "CLOUD_IAM_USER"
  }

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-02-07T22:44:16.656Z",
  "startTime": "2020-02-07T22:44:16.686Z",
  "endTime": "2020-02-07T22:44:20.437Z",
  "operationType": "CREATE_USER",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}

创建服务账号

在使用任何请求数据之前,请先进行以下替换:

  • SERVICE_ACCT:服务账号电子邮件地址
  • PROJECT_ID:项目 ID
  • INSTANCE_ID:您要向其添加服务账号的实例的 ID

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID/users

请求 JSON 正文:

{
    "name": "SERVICE_ACCT",
    "type": "CLOUD_IAM_SERVICE_ACCOUNT"
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
"kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-11-20T04:08:00.211Z",
  "startTime": "2020-11-20T04:08:00.240Z",
  "endTime": "2020-11-20T04:08:02.003Z",
  "operationType": "CREATE_USER",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}

将 IAM 群组添加到 Cloud SQL 实例

如需使用 IAM 群组身份验证并将 IAM 群组添加到 Cloud SQL 实例,请使用本部分中的某个过程。添加 IAM 群组后,您无需将单个群组成员添加到该实例。如需了解详情,请参阅自动将群组成员添加到 Cloud SQL 实例

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 从 SQL 导航菜单中选择用户
  4. 点击添加用户账号。系统会打开将用户账号添加到实例 instance_name 标签页。
  5. 点击 Cloud IAM 单选按钮。
  6. 主账号字段中添加要添加的群组的电子邮件地址。
  7. 点击添加。该群组现在位于用户列表中。
  8. 如果群组在创建用户账号后未被分配 cloudsql.instanceUser IAM 角色,则群组旁边会显示一个 三角形 图标。

    如需为群组成员授予登录权限,请点击该图标,然后选择添加 IAM 角色。如果该图标不再显示,则表示为群组的所有成员分配了可授予登录权限的角色。

gcloud

替换以下内容:

  • GROUP_EMAIL_ADDRESS:您要添加到实例的 Cloud Identity 群组的电子邮件地址。例如,example-group@example.com
  • INSTANCE_NAME:您要将群组添加到的实例的名称。

运行以下命令:

gcloud sql users create GROUP_EMAIL_ADDRESS \
  --instance=INSTANCE_NAME \
  --type=cloud_iam_group

Terraform

如需在启用了 IAM 数据库身份验证的实例上添加 IAM 用户和服务账号,请使用 Terraform 资源

resource "google_sql_database_instance" "default" {
  name             = "postgres-iam-group-auth-instance-name"
  region           = "us-west4"
  database_version = "POSTGRES_16"
  settings {
    tier = "db-custom-2-7680"
    database_flags {
      name  = "cloudsql.iam_authentication"
      value = "on"
    }
  }
  # set `deletion_protection` to true, will ensure that one cannot accidentally
  # delete this instance by use of Terraform whereas
  # `deletion_protection_enabled` flag protects this instance at the GCP level.
  deletion_protection = false
}

# Specify the email address of the Cloud Identity group to add to the instance
# This resource does not create a Cloud Identity group; the group must
# already exist

resource "google_sql_user" "iam_group" {
  name     = "example-group@example.com"
  instance = google_sql_database_instance.default.name
  type     = "CLOUD_IAM_GROUP"
}

data "google_project" "project" {
}

resource "google_project_iam_binding" "cloud_sql_user" {
  project = data.google_project.project.project_id
  role    = "roles/cloudsql.instanceUser"
  members = [
    "group:example-group@example.com"
  ]
}

应用更改

如需在 Google Cloud 项目中应用 Terraform 配置,请完成以下部分中的步骤。

准备 Cloud Shell

  1. 启动 Cloud Shell
  2. 设置要在其中应用 Terraform 配置的默认 Google Cloud 项目。

    您只需为每个项目运行一次以下命令,即可在任何目录中运行它。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    如果您在 Terraform 配置文件中设置显式值,则环境变量会被替换。

准备目录

每个 Terraform 配置文件都必须有自己的目录(也称为“根模块”)。

  1. Cloud Shell 中,创建一个目录,并在该目录中创建一个新文件。文件名必须具有 .tf 扩展名,例如 main.tf。在本教程中,该文件称为 main.tf
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. 如果您按照教程进行操作,可以在每个部分或步骤中复制示例代码。

    将示例代码复制到新创建的 main.tf 中。

    (可选)从 GitHub 中复制代码。如果端到端解决方案包含 Terraform 代码段,则建议这样做。

  3. 查看和修改要应用到您的环境的示例参数。
  4. 保存更改。
  5. 初始化 Terraform。您只需为每个目录执行一次此操作。
    terraform init

    (可选)如需使用最新的 Google 提供程序版本,请添加 -upgrade 选项:

    terraform init -upgrade

应用更改

  1. 查看配置并验证 Terraform 将创建或更新的资源是否符合您的预期:
    terraform plan

    根据需要更正配置。

  2. 通过运行以下命令并在提示符处输入 yes 来应用 Terraform 配置:
    terraform apply

    等待 Terraform 显示“应用完成!”消息。

  3. 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 Terraform 已创建或更新它们。

删除更改

如需删除更改,请执行以下操作:

  1. 如需停用删除防护,请在 Terraform 配置文件中将 deletion_protection 参数设置为 false
    deletion_protection =  "false"
  2. 运行以下命令并在提示符处输入 yes,以应用更新后的 Terraform 配置:
    terraform apply
  1. 运行以下命令并在提示符处输入 yes,以移除之前使用 Terraform 配置应用的资源:

    terraform destroy

REST v1

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:项目 ID
  • INSTANCE_ID:您要向其添加 Cloud Identity 群组的实例的 ID
  • GROUP_EMAIL:Cloud Identity 群组的电子邮件地址

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID/users

请求 JSON 正文:

{
  "name": "GROUP_EMAIL",
  "type": "CLOUD_IAM_GROUP"
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "DONE",
  "user": "example-group@example.com",
  "insertTime": "2023-12-07T22:44:16.656Z",
  "startTime": "2023-12-07T22:44:16.686Z",
  "endTime": "2023-12-07T22:44:20.437Z",
  "operationType": "CREATE_USER",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}

REST v1beta4

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:项目 ID
  • INSTANCE_ID:您要向其添加 Cloud Identity 群组的实例的 ID
  • GROUP_EMAIL:Cloud Identity 群组的电子邮件地址

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID/users

请求 JSON 正文:

{
  "name": "GROUP_EMAIL",
  "type": "CLOUD_IAM_GROUP"
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "DONE",
  "user": "example-group@example.com",
  "insertTime": "2023-12-07T22:44:16.656Z",
  "startTime": "2023-12-07T22:44:16.686Z",
  "endTime": "2023-12-07T22:44:20.437Z",
  "operationType": "CREATE_USER",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}

自动将群组成员添加到 Cloud SQL 实例

将 IAM 群组添加到 Cloud SQL 实例后,该群组的所有成员(用户和服务账号)都会继承 IAM 权限以向实例进行身份验证。您无需单独将群组成员添加到 Cloud SQL 实例。群组成员首次登录主实例并成功向主实例进行身份验证后,Cloud SQL 会为该群组成员创建群组用户账号或群组服务账号。您可以在首次成功登录后查看实例上列出的群组成员。

在发生故障切换时,只要故障切换实例具有适当的群组,IAM 群组用户就可以继续登录和创建。

如需详细了解登录,请参阅使用 IAM 数据库身份验证登录

将现有 IAM 用户迁移为使用 IAM 群组身份验证

类型为 CLOUD_IAM_USERCLOUD_IAM_SERVICE_ACCOUNT 的现有 IAM 用户不会使用 IAM 群组身份验证。

您可以迁移这些用户,以使用 IAM 群组身份验证。

  1. 将这些用户添加到群组。

  2. 将群组添加到实例。

  3. 向该群组分配足够的 IAM 权限,以便群组成员能够连接到您的实例。这些更改可能需要一段时间才能生效。如需详细了解传播时间,请参阅 访问权限更改传播

  4. 向要迁移到该群组的 IAM 用户分配数据库权限。

  5. 应用群组成员资格变更和 IAM 权限后,从您的实例中删除现有 IAM 用户。当 IAM 用户下次成功登录时,系统会将该用户重新创建为可使用 IAM 群组身份验证的 IAM 群组用户。

管理 Cloud SQL 实例上的群组成员

将 IAM 群组添加到 Cloud SQL 实例后,该群组的所有成员(用户或服务账号)都会继承 IAM 权限以向实例进行身份验证。您可以通过在 Cloud Identity 中管理该群组来控制对实例的访问权限。例如,如果您想为新用户授予对实例的访问权限,请在 Cloud Identity 中将该用户添加为群组成员。您无需在 Cloud SQL 实例级层单独移除或添加群组成员,因为对群组成员资格的更改会自动传播到 Cloud SQL 实例。对群组成员资格的更改(例如添加或移除成员)大约需要 15 分钟才能传播完毕。此时间是除了 IAM 更改所需的时间之外的时间。

在 PostgreSQL 中为 IAM 群组授予或撤消数据库权限会立即生效。例如,如果您撤消对某个表的访问权限,该 IAM 群组的成员会立即失去对该表的访问权限。

用户或服务账号可以是多个 IAM 群组的成员。如果用户或服务账号属于实例上的多个 IAM 群组,则他们拥有来自每个 IAM 群组的所有 IAM 权限和数据库权限。

在您将新成员(用户或服务账号)添加到 Cloud Identity 中的 IAM 群组且首次成功登录实例后,该成员会自动继承授予该群组的数据库权限。

向单个 IAM 用户或服务账号授予数据库权限

默认情况下,将单个 IAM 用户或服务添加到 Cloud SQL 实例后,该新账号不会被授予任何数据库的权限。他们只能对已被授予 PUBLIC 访问权限的任何数据库对象运行查询。

如果新账号需要其他访问权限,可以使用 GRANT 语句授予更多权限。如需查看您可以向用户和服务账号授予的完整权限列表,请参阅 GRANT 参考页面。从命令行运行 GRANT。

替换以下内容:

  • USERNAME:用户的电子邮件地址。 您必须使用英文引号括住电子邮件地址,因为它包含特殊字符(@.)。
  • TABLE_NAME:您要为用户授予其访问权限的表的名称。
grant select on TABLE_NAME to "USERNAME";

向 IAM 群组授予数据库权限

使用 IAM 群组身份验证时,您可以向 IAM 群组授予数据库权限,而不是向单个用户或服务账号授予权限。默认情况下,当您将 IAM 群组添加到 Cloud SQL 实例时,该群组没有数据库权限。

如需向 IAM 群组授予数据库权限,请使用 GRANT 语句。首次登录 Cloud SQL 实例后,每个群组成员(包括用户和服务账号)都会自动继承向该群组授予的数据库权限。

替换以下内容:

  • GROUP_NAME:Cloud Identity 群组的电子邮件地址,包括 @ 和域名。例如,如果 IAM 群组的电子邮件地址为 example-group@example.com,则群组名称为 example-group@example.com。您必须使用英文引号括住群组名称,因为该字符串包含特殊字符(@.
  • TABLE_NAME:您要为用户授予其访问权限的表的名称。

通过 psql 命令行运行 GRANT。

grant select on TABLE_NAME to "GROUP_NAME";

如需详细了解如何授予权限,请参阅 PostgreSQL 文档中的 GRANT 参考页面。

您向 IAM 群组授予的数据库权限会立即生效。

查看添加到 Cloud SQL 实例的 IAM 用户、服务账号和群组

如需查看已添加到 Cloud SQL 实例的 IAM 用户、服务账号和群组,请运行以下命令。

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 从 SQL 导航菜单中选择用户。 该页面会显示已添加到实例的 IAM 用户、服务账号和 Cloud Identity 群组的列表。
  4. 可选:如需查看已登录实例的 IAM 用户或服务账号的列表,请点击经过身份验证的 IAM 群组成员

gcloud

INSTANCE_NAME 替换为包含您要查看的群组的实例名称。

  gcloud sql users list --instance=INSTANCE_NAME
  

群组具有 CLOUD_IAM_GROUP 用户类型。

输出还会列出 Cloud SQL 实例上的用户和服务账号。

  • 属于群组成员的用户账号具有 CLOUD_IAM_GROUP_USER 类型。
  • 属于群组成员的服务账号具有 CLOUD_IAM_GROUP_SERVICE_ACCOUNT 类型。
  • 属于单个 IAM 数据库身份验证用户账号的用户账号具有 CLOUD_IAM_USER 类型。
  • 属于单个 IAM 数据库身份验证服务账号的服务账号具有 CLOUD_IAM_SERVICE_ACCOUNT 类型。

REST v1

以下请求使用 users.list 方法列出拥有 Cloud SQL 实例上的账号的用户。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:项目 ID
  • INSTANCE_ID:实例 ID

HTTP 方法和网址:

GET https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID/users/list

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:


{
  "kind": "sql#usersList",
  "items": [
    {
     "kind": "sql#user",
     "etag": "--redacted--",
     "name": "example-service-acct@PROJECT_ID.iam",
     "host": "",
     "instance": "INSTANCE_ID",
     "project": "PROJECT_ID",
     "type": "CLOUD_IAM_SERVICE_ACCOUNT"
    },
    {
      "kind": "sql#user",
      "etag": "--redacted--",
      "name": "another-example-service-acct@PROJECT_ID.iam",
      "host": "",
      "instance": "INSTANCE_ID",
      "project": "PROJECT_ID",
      "type": "CLOUD_IAM_GROUP_SERVICE_ACCOUNT"
     },
    {
      "kind": "sql#user",
      "etag": "--redacted--",
      "name": "postgres",
      "host": "",
      "instance": "INSTANCE_ID",
      "project": "PROJECT_ID",
    },
    {
      "kind": "sql#user",
      "etag": "--redacted--",
      "name": "example-user@example.com",
      "host": "",
      "instance": "INSTANCE_ID",
      "project": "PROJECT_ID",
      "type": "CLOUD_IAM_USER"
    },
    {
      "kind": "sql#user",
      "etag": "--redacted--",
      "name": "another-example-user@example.com",
      "host": "",
      "instance": "INSTANCE_ID",
      "project": "PROJECT_ID",
      "type": "CLOUD_IAM_GROUP_USER"
    },
    {
      "kind": "sql#user",
      "etag": "--redacted--",
      "name": "example-group@example.com",
      "host": "",
      "instance": "INSTANCE_ID",
      "project": "PROJECT_ID",
      "type": "CLOUD_IAM_GROUP"
    }
  ]
}

群组具有 CLOUD_IAM_GROUP 用户类型。

输出还会列出 Cloud SQL 实例上的用户和服务账号。

  • 属于群组成员的用户账号具有 CLOUD_IAM_GROUP_USER 类型。
  • 属于群组成员的服务账号具有 CLOUD_IAM_GROUP_SERVICE_ACCOUNT 类型。
  • 属于单个 IAM 数据库身份验证用户账号的用户账号具有 CLOUD_IAM_USER 类型。
  • 属于单个 IAM 数据库身份验证服务账号的服务账号具有 CLOUD_IAM_SERVICE_ACCOUNT 类型。

REST v1beta4

以下请求使用 users.list 方法列出拥有 Cloud SQL 实例上的账号的用户。

在使用任何请求数据之前,请先进行以下替换:

  • project-id:您的项目 ID
  • instance-id:所需的实例 ID

HTTP 方法和网址:

GET https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/users

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "kind": "sql#usersList",
  "items": [
    {
      "kind": "sql#user",
      "etag": "--redacted--",
      "name": "sqlserver",
      "host": "",
      "instance": "instance-id",
      "project": "project-id",
      "sqlserverUserDetails": {
        "serverRoles": [
          "CustomerDbRootRole"
        ]
      }
    },
    {
      "kind": "sql#user",
      "etag": "--redacted--",
      "name": "user-id-1",
      "host": "",
      "instance": "instance-id",
      "project": "project-id",
      "sqlserverUserDetails": {
        "serverRoles": [
          "CustomerDbRootRole"
        ]
      }
    },
    {
      "kind": "sql#user",
      "etag": "--redacted--",
      "name": "user-id-2",
      "host": "",
      "instance": "instance-id",
      "project": "project-id",
      "sqlserverUserDetails": {
        "serverRoles": [
          "CustomerDbRootRole"
        ]
      }
    },
    {
      ...
    },
    {
      ...
    }
  ]
}

群组具有 CLOUD_IAM_GROUP 用户类型。

输出还会列出 Cloud SQL 实例上的用户和服务账号。

  • 属于群组成员的用户账号具有 CLOUD_IAM_GROUP_USER 类型。
  • 属于群组成员的服务账号具有 CLOUD_IAM_GROUP_SERVICE_ACCOUNT 类型。
  • 属于单个 IAM 数据库身份验证用户账号的用户账号具有 CLOUD_IAM_USER 类型。
  • 属于单个 IAM 数据库身份验证服务账号的服务账号具有 CLOUD_IAM_SERVICE_ACCOUNT 类型。

从 Cloud SQL 实例中移除单个 IAM 用户或服务账号

如需从 Cloud SQL 实例中移除不属于群组成员的单个用户或服务账号,请使用以下命令删除该账号:

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 从 SQL 导航菜单中选择用户
  4. 针对您要移除的用户,点击
  5. 选择移除。这样只会撤消对此实例的访问权限。

gcloud

撤消用户

使用电子邮件地址(如 example-user@example.com)来标识用户。

替换以下内容:

  • USERNAME:电子邮件地址。
  • INSTANCE_NAME:您要从中移除用户的实例的名称。
gcloud sql users delete USERNAME \
--instance=INSTANCE_NAME

删除单个服务账号

替换以下内容:

  • SERVICE_ACCT:服务账号的电子邮件地址。
  • INSTANCE_NAME:您要从中移除用户的实例的名称。
gcloud sql users delete SERVICE_ACCT \
--instance=INSTANCE_NAME

REST v1

以下请求使用 users.delete 方法删除指定的用户账号。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的项目 ID
  • INSTANCE_ID:所需的实例 ID
  • USERNAME:用户或服务账号的电子邮件地址

HTTP 方法和网址:

DELETE https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID/users?host=&name=USERNAME

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-02-07T22:38:41.217Z",
  "startTime": "2020-02-07T22:38:41.217Z",
  "endTime": "2020-02-07T22:38:44.801Z",
  "operationType": "DELETE_USER",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}

REST v1beta4

以下请求使用 users.delete 方法删除指定的用户账号。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的项目 ID
  • INSTANCE_ID:所需的实例 ID
  • USERNAME:用户或服务账号的电子邮件地址

HTTP 方法和网址:

DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID/users?host=&name=USERNAME

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-02-07T22:38:41.217Z",
  "startTime": "2020-02-07T22:38:41.217Z",
  "endTime": "2020-02-07T22:38:44.801Z",
  "operationType": "DELETE_USER",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}

从 Cloud SQL 实例中移除 IAM 群组成员

您可以通过以下两种方式从 Cloud SQL 实例中移除 IAM 群组成员:

  • 自动移除
  • 手动移除

自动移除

如需移除 IAM 群组成员,您需要从 Cloud Identity 中适用的 IAM 群组中移除其成员资格。在 IAM 群组用户失去 Cloud Identity 中所有适用群组的成员资格后,Cloud SQL 会自动从实例中移除这些群组用户。唯一的例外情况是拥有数据库对象的群组用户。您必须手动移除这些群组用户。

对群组成员资格的更改(例如添加或移除成员)大约需要 15 分钟才能传播完毕。此时间是除了 IAM 更改所需的时间之外的时间。

手动移除

如果无法自动移除 IAM 群组用户,您可以手动将其移除。您无法使用 gcloud CLI、Google Cloud 控制台、Terraform 或 Cloud SQL Admin API 从 Cloud SQL 实例中手动移除 IAM 群组用户。不过,具有超级用户权限的数据库用户可以使用 PostgreSQL 客户端中的 DROP USER 语句从 Cloud SQL 实例中手动删除 IAM 群组用户。

从 Cloud SQL 实例中手动移除 IAM 群组用户后,请确保同时将其从 Cloud Identity 中的 IAM 群组中移除,以防止进一步登录 Cloud SQL 实例。

从 Cloud SQL 实例中删除 IAM 群组

您可以从 Cloud SQL 实例中删除添加的 IAM 群组。从实例中删除 IAM 群组后,属于该 IAM 群组的所有用户账号和服务账号都会失去授予该 IAM 群组的任何数据库权限。此外,以下条件也适用:

  • 在从 IAM 群组中移除 cloudsql.instances.login IAM 权限之前,属于该群组的用户和服务账号仍可以登录。
  • 如果删除某个群组导致 IAM 群组用户或服务账号不属于实例上的其他群组,则 Cloud SQL 会从实例中移除 IAM 群组用户或服务账号。
  • 不过,如果 IAM 群组用户拥有实例上的数据库对象,则您必须先重新分配该对象的所有权,然后才能手动删除该用户

如果您从 Cloud SQL 实例中删除所有 IAM 群组,则所有 IAM 群组用户和服务账号都会失去其所有数据库权限。此外,以下条件也适用:

  • 所有 IAM 群组用户和服务账号都无法登录实例。
  • Cloud SQL 还会自动从实例中移除所有 IAM 群组用户和服务账号。
  • 不过,如果 IAM 群组用户拥有实例上的数据库对象,则您必须先重新分配该对象的所有权,然后才能手动删除该用户

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 从 SQL 导航菜单中选择用户
  4. 点击要移除的群组对应的
  5. 选择移除。这样只会撤消对此实例的访问权限。

gcloud

如需从实例中删除 Cloud Identity 群组,请使用 gcloud sql users delete 命令。

替换以下内容:

  • GROUP_NAME:Cloud Identity 群组电子邮件地址的第一部分。例如,使用电子邮件地址 example-group@example.com 时,Cloud Identity 群组名称为 example-group
  • INSTANCE_NAME:包含您要删除的 Cloud Identity 群组的 Cloud SQL 实例的名称。
gcloud sql users delete GROUP_NAME \
   --instance=INSTANCE_NAME

从 IAM 群组中移除 IAM 登录权限

如果您从 IAM 群组中撤消 cloudsql.instanceUser 角色,则该群组的所有成员都将无法登录项目中的任何 Cloud SQL 实例。用户账号或服务账号只有在属于仍具有登录权限的其他 IAM 群组的成员时才能登录实例。

如需撤消 Cloud Identity 群组的角色,请参阅撤消单个角色

从 IAM 群组中移除用户

您可以从 Cloud Identity 中的 IAM 群组中移除 IAM 群组成员(例如用户或服务账号)。

在通过 IAM 传播移除操作后,除非用户已从其他群组收到登录权限,或者直接被授予登录权限,否则将无法再登录数据库。此外,从群组中移除的用户会失去该群组的数据库权限。

如果 IAM 群组用户不属于实例上的任何群组,则 Cloud SQL 会自动从实例中移除该用户。不过,如果 Cloud SQL 检测到 IAM 群组用户拥有实例上的某个对象,则不会移除该用户。管理员必须重新分配该对象的所有权,然后手动移除该用户

在审核日志中查看登录信息

您可以启用审核日志以捕获对数据库的 IAM 登录。如果出现登录问题,您可以使用审核日志来诊断问题。

配置后,您可以使用日志浏览器查看成功登录的数据访问审核日志

对于 IAM 群组身份验证,审核日志会显示单个用户和服务账号的活动和登录。

例如,日志可能包含类似如下所示的信息:

{
 insertId: "..."
 logName: "projects/.../logs/cloudaudit.googleapis.com%2Fdata_access"
 protoPayload: {
  @type: "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail: "..."
  }
  authorizationInfo: [
   0: {
    granted: true
    permission: "cloudsql.instances.login"
    resource: "instances/..."
    resourceAttributes: {
    }
   }
  ]
  methodName: "cloudsql.instances.login"
  request: {
   @type: "type.googleapis.com/google.cloud.sql.authorization.v1.InstancesLoginRequest"
   clientIpAddress: "..."
   database: "..."
   databaseSessionId: ...
   instance: "projects/.../locations/us-central1/instances/..."
   user: "..."
  }
  requestMetadata: {
   callerIp: "..."
   destinationAttributes: {
   }
   requestAttributes: {
    auth: {
    }
    time: "..."
   }
  }
  resourceName: "instances/..."
  serviceName: "cloudsql.googleapis.com"
  status: {
  }
 }
 receiveTimestamp: "..."
 resource: {
  labels: {
   database_id: "...:..."
   project_id: "..."
   region: "us-central"
  }
  type: "cloudsql_database"
 }
 severity: "INFO"
 timestamp: "..."
}

排查登录失败问题

尝试登录失败时,出于安全考虑,PostgreSQL 会返回最少的错误消息。例如:

PGPASSWORD=not-a-password psql --host=... --username=... --dbname=...
psql: error: could not connect to server: FATAL:  Cloud SQL IAM user authentication failed for user "..."
FATAL:  pg_hba.conf rejects connection for host "...", user "...", database "...", SSL off

您可以查看 PostgreSQL 错误日志以详细了解错误。如需了解详情,请参阅查看日志

例如,对于前面的错误,以下日志条目说明了您可以执行来解决该问题的操作。

F ... [152172]: [1-1] db=...,user=... FATAL:  Cloud SQL IAM user authentication failed for user "..."
I ... [152172]: [2-1] db=...,user=... DETAIL:  Request is missing required authentication credential. Expected OAuth 2 access token, log in cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.

检查您收到的错误消息。如果消息未指明您使用的是“Cloud SQL IAM 用户身份验证”还是“Cloud SQL IAM 服务账号身份验证”,请验证用于登录的数据库用户类型是 CLOUD_IAM_USERCLOUD_IAM_SERVICE_ACCOUNT。您可以使用 Google Cloud 控制台或 gcloud sql users list 命令检查此项。对于 IAM 用户,验证数据库用户名是否为 IAM 用户的电子邮件地址。

如果您使用的是 IAM 数据库身份验证,请查看错误消息的详细信息。您可以在数据库错误日志中找到错误消息。如果消息指明您发送用作密码的访问令牌 (OAuth 2.0) 无效,您可以使用 gcloud auth application-default print-access-token gcloud 命令查找令牌的详细信息,如下所示:

curl -H "Content-Type: application/x-www-form-urlencoded" \
-d "access_token=$(gcloud auth application-default print-access-token)" \
https://www.googleapis.com/oauth2/v1/tokeninfo

验证该令牌适用于预期的 IAM 用户或服务账号,并且未过期。

如果详细信息指明缺少权限,请验证已使用预定义的 Cloud SQL Instance User 角色或实例项目的 IAM 政策中的自定义角色为 IAM 用户或服务账号授予了 cloudsql.instances.login 权限。如需其他帮助,请使用 IAM 政策问题排查工具

如果由于 IAM 数据库身份验证不可用而导致登录失败,则用户可以使用默认的 PostgreSQL 用户名和密码登录。这种登录方法仍可为用户提供整个数据库的访问权限。 验证连接是否为安全连接。

排查使用 IAM 群组身份验证的用户账号的问题

本部分列出了 IAM 群组身份验证的问题排查场景。

无法将群组添加到数据库

尝试将群组添加到实例时,您会收到以下错误:

(gcloud.sql.users.create) HTTPError 400: Invalid request: Provided CLOUD_IAM_GROUP: EMAIL, does not exist.

请确保您提供的电子邮件地址是有效的群组。

如果该群组尚不存在,请创建该群组。如需详细了解如何创建群组,请参阅在 Google Cloud 控制台中创建和管理 Google 群组

如果您收到以下错误:

(gcloud.sql.users.create) HTTPError 400: Invalid request: IAM Group Authentication is disabled.

然后,您需要对 Cloud SQL 实例进行以下维护更新,才能使用 IAM 群组身份验证:

R20240514.00_04 或更高版本

您可以使用自助维护功能将维护更新应用于实例。如需了解详情,请参阅自助维护

现有 IAM 用户或服务账号未继承授予其 IAM 群组的数据库权限

如果现有 IAM 用户账号或服务账号未继承其群组的正确数据库权限,请完成以下步骤:

  1. 在 Google Cloud 控制台中,转到 IAM 页面。

    进入 IAM

    验证该账号是否为添加到 Cloud SQL 实例的群组的成员。

  2. 列出实例上的用户账号和服务账号。

    gcloud sql users list --instance=INSTANCE_NAME

    在输出中,检查用户账号或服务账号是否列为 CLOUD_IAM_USERCLOUD_IAM_SERVICE_ACCOUNT

  3. 如果用户账号或服务账号列为 CLOUD_IAM_USERCLOUD_IAM_SERVICE_ACCOUNT,请从实例中移除该账号。您要移除的账号是一个单独的 IAM 账号,不会继承群组的数据库权限。

  4. 使用用户账号或服务账号重新登录该实例。

    再次登录实例,使用正确的账号类型 CLOUD_IAM_GROUP_USERCLOUD_IAM_GROUP_SERVICE_ACCOUNT 重新创建账号。

后续步骤