创建服务代理并授予角色

在 Google Cloud 中,当您启用和使用 Google Cloud 服务时,系统会自动创建项目级、文件夹级和组织级服务代理。有时,这些服务代理也会自动获得角色,以便代表您创建和访问资源。

如有必要,您还可以要求 Google Cloud 在您使用服务之前为服务创建项目级、文件夹级和组织级服务代理。如果要求 Google Cloud 创建服务代理,您可以在使用服务之前向服务代理授予角色。如果尚未创建服务代理,则无法向服务代理授予角色。

如果您使用以下策略之一来管理允许政策,此选项会非常有用:

  • 声明式框架,例如 Terraform 如果您的 Terraform 配置未包含服务代理的角色,那么在您应用配置时,这些角色会被撤消。通过创建服务代理并在 Terraform 配置中为其授予角色,您可以确保这些角色不会被撤消。
  • 将当前允许政策的副本存储在代码库中的政策即代码系统。如果您让 Google Cloud 自动向服务代理授予角色,这些角色会显示在您的实际许可政策中,但不会显示在您存储的许可政策副本中。为了解决此不一致问题,您可能会错误地撤消这些角色。通过创建服务代理并主动向其授予角色,您可以帮助防止代码存储库与实际的许可政策之间出现偏差。

触发服务代理创建后,您必须向服务代理授予通常会自动授予的角色。如果您不这样做,某些服务可能无法正常运行。这是因为根据用户请求创建的服务代理不会自动获得角色。

准备工作

  • Enable the Resource Manager API.

    Enable the API

  • 了解服务代理

所需的角色

触发服务代理创建不需要任何 IAM 权限。但是,您需要拥有此页面上的其他任务的特定 IAM 权限:

  • 如需获得列出可用服务及其端点所需的权限,请让管理员向您授予要为其列出可用服务的项目、文件夹或组织的 Service Usage Viewer (roles/serviceusage.serviceUsageViewer) IAM 角色。 如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

    此预定义角色包含列出可用服务及其端点所需的 serviceusage.services.list 权限。

    您也可以使用自定义角色或其他预定义角色来获取此权限。

  • 如需获得授予服务代理访问权限所需的权限,请让管理员向您授予要针对其授予访问权限的项目、文件夹或组织的以下 IAM 角色:

    • 授予服务代理对项目的访问权限: Project IAM Admin (roles/resourcemanager.projectIamAdmin)
    • 向服务代理授予对文件夹的访问权限: Folder Admin (roles/resourcemanager.folderAdmin)
    • 向服务代理授予对项目、文件夹和组织的访问权限:Organization Admin (roles/resourcemanager.organizationAdmin)

    如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

    这些预定义角色包含授予服务代理访问权限所需的权限。如需查看所需的确切权限,请展开所需权限部分:

    所需权限

    如需向服务代理授予访问权限,您需要具有以下权限:

    • 向服务代理授予对项目的访问权限:
      • resourcemanager.projects.getIamPolicy
      • resourcemanager.projects.setIamPolicy
    • 向服务代理授予对文件夹的访问权限:
      • resourcemanager.folders.getIamPolicy
      • resourcemanager.folders.setIamPolicy
    • 向服务代理授予对组织的访问权限:
      • resourcemanager.organizations.getIamPolicy
      • resourcemanager.organizations.setIamPolicy

    您也可以使用自定义角色或其他预定义角色来获取这些权限。

确定要创建的服务代理

如需确定您需要让 Google Cloud 创建的项目级、文件夹级和组织级服务代理,请执行以下操作:

  1. 列出您使用的服务及其 API 端点。如需查看所有可用服务及其端点,请使用以下方法之一:

    控制台

    进入 Google Cloud 控制台中的 API 库页面。

    转到 API 库

    API 端点是其他详细信息部分中列出的服务名称

    gcloud

    gcloud services list 命令会列出项目的所有可用服务。

    在使用下面的命令数据之前,请先进行以下替换:

    • EXPRESSION:可选。用于过滤结果的表达式。例如,以下表达式会过滤名称包含 googleapis.com 但不包含 sandbox 的所有服务:

      name ~ googleapis.com AND name !~ sandbox

      如需查看过滤条件表达式列表,请参阅 gcloud topic filters

    • LIMIT:可选。列出的结果数上限。默认值为 unlimited

    执行以下命令:

    Linux、macOS 或 Cloud Shell

    gcloud services list --available --filter='EXPRESSION' --limit=LIMIT

    Windows (PowerShell)

    gcloud services list --available --filter='EXPRESSION' --limit=LIMIT

    Windows (cmd.exe)

    gcloud services list --available --filter='EXPRESSION' --limit=LIMIT

    响应包含所有可用服务的名称和标题。API 端点是 NAME 字段中的值。

    REST

    Service Usage API 的 services.list 方法可列出项目的所有可用服务。

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

    • RESOURCE_TYPE:您要为其列出可用服务的资源类型。请使用 projectsfoldersorganizations
    • RESOURCE_ID:要为其列出可用服务的 Google Cloud 项目、文件夹或组织的 ID。项目 ID 是字母数字字符串,例如 my-project。 文件夹和组织 ID 是数字,例如 123456789012
    • PAGE_SIZE:可选。要包含在响应中的服务的数量。默认值为 50,最大值为 200。如果服务数大于页面大小,则响应中会包含分页令牌,您可以使用该令牌检索下一页结果。
    • NEXT_PAGE_TOKEN:可选。此方法之前的响应中返回的分页令牌。如果已指定,则服务列表将从上一个请求结束的位置开始。

    HTTP 方法和网址:

    GET https://serviceusage.googleapis.com/v1/RESOURCE_TYPE/RESOURCE_ID/services?pageSize=PAGE_SIZE&pageToken=NEXT_PAGE_TOKEN

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

    响应包含资源的所有可用服务的名称和标题。如果可用服务的数量大于页面大小,响应中还会包含分页令牌。

    API 端点是 name 字段中的值。

  2. 服务代理参考文档页面上,搜索每个 API 端点。

    如果表中列出了该端点,请找到该端点的所有服务代理。忽略电子邮件地址包含 IDENTIFIER 占位符的所有服务代理,这些服务代理适用于服务专属资源,而不适用于项目、文件夹或组织。

    对于每个项目级、文件夹级和组织级服务代理,请记录以下信息:

    • 服务代理的电子邮件地址的格式。
    • 服务代理获得的角色(如果有)。

触发服务代理创建

了解需要创建哪些服务代理后,您可以要求 Google Cloud 创建这些服务代理。

当您要求 Google Cloud 创建服务代理时,您会为其提供服务和资源。然后,Google Cloud 会为该服务和资源创建所有服务代理。

gcloud

对于需要创建服务代理的每项服务,请执行以下操作:

  1. 查看该服务的服务代理电子邮件地址。使用电子邮件地址中的占位符来确定您需要为哪些资源创建服务代理:

    占位符 在哪里创建服务代理
    PROJECT_NUMBER 要在其中使用服务的每个项目
    FOLDER_NUMBER 要在其中使用服务的每个文件夹
    ORGANIZATION_NUMBER 要在其中使用服务的每个组织

  2. 为每个资源创建服务代理。

    gcloud beta services identity create 命令会为指定的 API 和资源创建所有服务代理。

    在使用下面的命令数据之前,请先进行以下替换:

    • ENDPOINT:要为其创建服务代理的 API 的端点,例如 aiplatform.googleapis.com
    • RESOURCE_TYPE:您要为其创建服务代理的资源类型。请使用 projectfolderorganization
    • RESOURCE_ID:要为其创建服务代理的 Google Cloud 项目、文件夹或组织的 ID。项目 ID 是字母数字字符串,例如 my-project。 文件夹和组织 ID 是数字,例如 123456789012

      您一次只能为一个资源创建服务代理。如果您需要为多个资源创建服务代理,请为每个资源运行一次该命令。

    执行以下命令:

    Linux、macOS 或 Cloud Shell

    gcloud beta services identity create --service=ENDPOINT \
        --RESOURCE_TYPE=RESOURCE_ID

    Windows (PowerShell)

    gcloud beta services identity create --service=ENDPOINT `
        --RESOURCE_TYPE=RESOURCE_ID

    Windows (cmd.exe)

    gcloud beta services identity create --service=ENDPOINT ^
        --RESOURCE_TYPE=RESOURCE_ID

    响应包含服务的主要服务代理的电子邮件地址。此电子邮件地址包含您为其创建服务代理的项目、文件夹或组织的数字 ID。

    如果服务没有主要服务代理,则响应不包含电子邮件地址。

    以下是具有主要服务代理的服务的响应示例。

    Service identity created: service-232332569935@gcp-sa-aiplatform.iam.gserviceaccount.com
    

  3. 可选:在响应中记录服务代理电子邮件地址(如果有)。此电子邮件地址标识服务的主要服务代理。您可以使用此标识符向主服务代理授予角色。

Terraform

如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令。 如需了解详情,请参阅 Terraform 提供程序参考文档

对于需要创建服务代理的每项服务,请执行以下操作:

  1. 查看该服务的服务代理电子邮件地址。使用电子邮件地址中的占位符来确定您需要为哪些资源创建服务代理:

    占位符 在哪里创建服务代理
    PROJECT_NUMBER 要在其中使用服务的每个项目
    FOLDER_NUMBER 要在其中使用服务的每个文件夹
    ORGANIZATION_NUMBER 要在其中使用服务的每个组织

  2. 为每个资源创建服务代理。例如,以下代码会为 AI Platform 创建所有项目级服务代理:

data "google_project" "default" {
}

# Create all project-level aiplatform.googleapis.com service agents
resource "google_project_service_identity" "default" {
  provider = google-beta

  project = data.google_project.default.project_id
  service = "aiplatform.googleapis.com"
}

REST

对于需要创建服务代理的每项服务,请执行以下操作:

  1. 查看该服务的服务代理电子邮件地址。使用电子邮件地址中的占位符来确定您需要为哪些资源创建服务代理:

    占位符 在哪里创建服务代理
    PROJECT_NUMBER 要在其中使用服务的每个项目
    FOLDER_NUMBER 要在其中使用服务的每个文件夹
    ORGANIZATION_NUMBER 要在其中使用服务的每个组织

  2. 为每个资源创建服务代理。

    Service Usage API 的 services.generateServiceIdentity 方法会为指定的 API 和资源创建所有服务代理。

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

    • RESOURCE_TYPE:您要为其创建服务代理的资源类型。请使用 projectsfoldersorganizations
    • RESOURCE_ID:要为其创建服务代理的 Google Cloud 项目、文件夹或组织的 ID。项目 ID 是字母数字字符串,例如 my-project。 文件夹和组织 ID 是数字,例如 123456789012

      您一次只能为一个资源创建服务代理。如果您需要为多个资源创建服务代理,请为每个资源发送一个请求。

    • ENDPOINT:要为其创建服务代理的 API 的端点,例如 aiplatform.googleapis.com

    HTTP 方法和网址:

    POST https://serviceusage.googleapis.com/v1beta1/RESOURCE_TYPE/RESOURCE_ID/services/ENDPOINT:generateServiceIdentity

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

    响应包含一个 Operation,用于指示您的请求的状态。要检查操作的状态,请使用 operations.get 方法。

    已完成的操作包含服务的主要服务代理的电子邮件地址。此电子邮件地址包含您为其创建服务代理的项目、文件夹或组织的数字 ID。

    如果服务没有主要服务代理,则响应不包含电子邮件地址。

    以下示例展示了具有主要服务代理的服务的已完成操作。

    {
      "name": "operations/finished.DONE_OPERATION",
      "done": true,
      "response": {
        "@type": "type.googleapis.com/google.api.serviceusage.v1beta1.ServiceIdentity",
        "email": "service-232332569935@gcp-sa-aiplatform.iam.gserviceaccount.com",
        "uniqueId": "112245693826560101651"
      }
    }
    

  3. 可选:在响应中记录服务代理电子邮件地址(如果有)。此电子邮件地址标识服务的主要服务代理。您可以使用此标识符向主服务代理授予角色。

为服务代理授予角色

Google Cloud 为您的项目、文件夹和组织创建必要的服务代理后,您可以使用服务代理的电子邮件地址向其授予角色。

如果您要求 Google Cloud 创建服务代理,则必须向这些服务代理授予通常会自动授予的角色。如果您不这样做,某些服务可能无法正常运行。这是因为根据用户请求创建的服务代理不会自动获得角色。

如需了解如何识别自动授予的角色,请参阅识别要创建的服务代理

找到服务代理的电子邮件地址

如需查找服务代理的电子邮件地址,请执行以下操作:

gcloud

  1. 如果您尚未找到服务代理的电子邮件地址格式,请先找到。此格式记录在服务代理参考文档中。

  2. 将电子邮件地址中的所有占位符替换为相应的项目、文件夹或组织编号。

或者,如果服务代理是主要服务代理,则可以通过为服务触发服务代理创建来获取其电子邮件地址。用于触发服务代理创建的命令会返回主要服务代理的电子邮件地址。

Terraform

如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令。 如需了解详情,请参阅 Terraform 提供程序参考文档

  1. 如果您尚未找到服务代理的电子邮件地址格式,请先找到。此格式记录在服务代理参考文档中。

  2. 将电子邮件地址中的所有占位符替换为引用相应项目、文件夹或组织编号的表达式。

    例如,请考虑以下情况:

    • 电子邮件地址的格式为 service-PROJECT_NUMBER@gcp-sa-aiplatform-cc.iam.gserviceaccount.com
    • 服务代理适用于标记为 default 的项目

    在本例中,服务代理的电子邮件地址如下所示:

    service-${data.google_project.default.number}@gcp-sa-aiplatform-cc.iam.gserviceaccount.com
    

或者,如果服务代理是某项服务的主要服务代理,则可以从 google_project_service_identity 资源的 email 属性中获取其电子邮件地址。

例如,如果您有一个标记为 defaultgoogle_project_service_identity 代码块,则可以使用以下表达式获取该服务的主要服务代理的电子邮件地址:

${google_project_service_identity.default.email}

REST

  1. 如果您尚未找到服务代理的电子邮件地址格式,请先找到。此格式记录在服务代理参考文档中。

  2. 将电子邮件地址中的所有占位符替换为相应的项目、文件夹或组织编号。

或者,如果服务代理是主要服务代理,则可以通过为服务触发服务代理创建来获取其电子邮件地址。用于触发服务代理创建的命令会返回主要服务代理的电子邮件地址。

为服务代理授予角色

找到服务代理的电子邮件地址后,您可以向其授予角色,就像向任何其他主账号授予角色一样。

控制台

  1. 在 Google Cloud 控制台中,前往 IAM 页面。

    转到 IAM

  2. 选择一个项目、文件夹或组织。

  3. 点击 授予访问权限,然后输入服务代理的电子邮件地址。

  4. 从下拉列表中选择要授予的角色。

  5. 可选:为角色添加条件

  6. 点击保存。系统会向服务代理授予资源上的角色。

gcloud

add-iam-policy-binding 命令使您可以快速向主账号授予角色。

在使用下面的命令数据之前,请先进行以下替换:

  • RESOURCE_TYPE:要管理访问权限的资源类型。请使用 projectsresource-manager foldersorganizations

  • RESOURCE_ID:您的 Google Cloud 项目、文件夹或组织 ID。项目 ID 为字母数字,例如 my-project。 文件夹和组织 ID 是数字,例如 123456789012

  • PRINCIPAL:主账号(或成员)的标识符,通常其格式如下:PRINCIPAL_TYPE:ID。例如 user:my-user@example.com。如需查看 PRINCIPAL 可以采用的值的完整列表,请参阅政策绑定参考文档

    对于主账号类型 user,标识符中的域名必须是 Google Workspace 网域或 Cloud Identity 网域。如需了解如何设置 Cloud Identity 网域,请参阅 Cloud Identity 概览

  • ROLE_NAME:要撤消的角色的名称。请采用以下某种格式:

    • 预定义角色:roles/SERVICE.IDENTIFIER
    • 项目级自定义角色:projects/PROJECT_ID/roles/IDENTIFIER
    • 组织级自定义角色:organizations/ORG_ID/roles/IDENTIFIER

    如需了解完整的预定义角色的列表,请参阅了解角色

  • CONDITION:要添加到角色绑定的条件。如果您不想添加条件,请使用值 None。如需详细了解条件,请参阅条件概览

执行以下命令:

Linux、macOS 或 Cloud Shell

gcloud RESOURCE_TYPE add-iam-policy-binding RESOURCE_ID \
    --member=PRINCIPAL --role=ROLE_NAME \
    --condition=CONDITION

Windows (PowerShell)

gcloud RESOURCE_TYPE add-iam-policy-binding RESOURCE_ID `
    --member=PRINCIPAL --role=ROLE_NAME `
    --condition=CONDITION

Windows (cmd.exe)

gcloud RESOURCE_TYPE add-iam-policy-binding RESOURCE_ID ^
    --member=PRINCIPAL --role=ROLE_NAME ^
    --condition=CONDITION

响应中包含更新后的 IAM 政策。

Terraform

如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令。 如需了解详情,请参阅 Terraform 提供程序参考文档

# Grant the AI Platform Custom Code Service Account the Vertex AI Custom
# Code Service Agent role (roles/aiplatform.customCodeServiceAgent)
resource "google_project_iam_member" "custom_code" {
  project = data.google_project.default.project_id
  role    = "roles/aiplatform.customCodeServiceAgent"
  member  = "serviceAccount:service-${data.google_project.default.number}@gcp-sa-aiplatform-cc.iam.gserviceaccount.com"
}

# Grant the primary aiplatform.googleapis.com service agent (AI Platform
# Service Agent) the Vertex AI Service Agent role
# (roles/aiplatform.serviceAgent)
resource "google_project_iam_member" "primary" {
  project = data.google_project.default.project_id
  role    = "roles/aiplatform.serviceAgent"
  member  = "serviceAccount:${google_project_service_identity.default.email}"
}

REST

如需使用 REST API 授予角色,请使用“读取-修改-写入”模式:

  1. 通过调用 getIamPolicy() 读取当前允许政策。

    Resource Manager API 的 getIamPolicy 方法可获取项目、文件夹或组织的允许政策。

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

    • API_VERSION:要使用的 API 版本。对于项目和组织,请使用 v1。对于文件夹,请使用 v2
    • RESOURCE_TYPE:您要管理其政策的资源类型。使用值 projectsfoldersorganizations
    • RESOURCE_ID:您的 Google Cloud 项目、组织或文件夹 ID。 项目 ID 是字母数字字符串,例如 my-project。文件夹和组织 ID 是数字,例如 123456789012
    • POLICY_VERSION:要返回的政策版本。请求应指定最新的政策版本,即政策版本 3。如需了解详情,请参阅在获取政策时指定政策版本

    HTTP 方法和网址:

    POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:getIamPolicy

    请求 JSON 正文:

    {
      "options": {
        "requestedPolicyVersion": POLICY_VERSION
      }
    }
    

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

    响应包含资源的允许政策。例如:

    {
      "version": 1,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "role": "roles/owner",
          "members": [
            "user:owner@example.com"
          ]
        }
      ]
    }
    

  2. 使用文本编辑器或以编程方式修改资源的允许政策,以添加或移除任何主账号或角色绑定。例如,您可以添加新的角色绑定、移除现有的角色绑定,或者在现有角色绑定中添加主账号或从现有角色绑定中移除主账号。

  3. 通过调用 setIamPolicy() 写入更新后的允许政策。

    Resource Manager API 的 setIamPolicy 方法会将请求中的政策设置为项目、文件夹或组织的新允许政策。

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

    • API_VERSION:要使用的 API 版本。对于项目和组织,请使用 v1。对于文件夹,请使用 v2
    • RESOURCE_TYPE:您要管理其政策的资源类型。使用值 projectsfoldersorganizations
    • RESOURCE_ID:您的 Google Cloud 项目、组织或文件夹 ID。 项目 ID 是字母数字字符串,例如 my-project。文件夹和组织 ID 是数字,例如 123456789012
    • POLICY:您要设置的政策的 JSON 格式。如需详细了解政策的格式,请参阅政策参考文档

    HTTP 方法和网址:

    POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:setIamPolicy

    请求 JSON 正文:

    {
      "policy": POLICY
    }
    

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

    响应包含更新后的允许政策。

后续步骤