创建服务代理并授予角色

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

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

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

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

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

须知事项

  • 启用 Resource Manager API。

    启用 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
    }
    

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

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

后续步骤