如何授权 Cloud Build 部署到不同项目中的 Firebase 托管?
How can I authorize Cloud Build to deploy to Firebase Hosting in a different project?
我有 GCP 项目 A
和 Firebase 项目 B
(在单独的 GCP 项目中)。我正在尝试在 A
中使用 Cloud Build 构建 Web 应用程序并将其部署到 B
中的 Firebase 托管。
在 B
的 IAM 页面中,我已授予 A
的 <id>@cloudbuild.gserviceaccount.com
服务帐户 API Keys Admin
、Firebase Admin
和 Service Account User
中描述的角色.
A
使用的 Cloud Build 配置的最后一步如下:
- id: firebase_deploy
name: gcr.io/$PROJECT_ID/firebase
entrypoint: sh
args:
- '-c'
- |
firebase use $_FIREBASE_PROJECT_ID
firebase target:apply hosting prod $_FIREBASE_HOSTING_TARGET
firebase deploy --project=$_FIREBASE_PROJECT_ID --only=hosting,firestore:rules
我将 _FIREBASE_PROJECT_ID
替换变量设置为 B
,将 _FIREBASE_HOSTING_TARGET
变量设置为我用于站点的主机别名。
当我触发构建时,它失败并出现以下错误:
...
Step #3 - "firebase_deploy": Error: Invalid project selection, please verify project B exists and you have access.
Step #3 - "firebase_deploy":
Step #3 - "firebase_deploy": Error: Must have an active project to set deploy targets. Try firebase use --add
Step #3 - "firebase_deploy":
Step #3 - "firebase_deploy": Error: Failed to get Firebase project B. Please make sure the project exists and your account has permission to access it.
Finished Step #3 - "firebase_deploy"
我怀疑问题可能出在我没有先 运行 Firebase CLI 的额外登录步骤。为此,我似乎需要在本地 运行 firebase login:ci
生成一个令牌,然后通过 FIREBASE_TOKEN
环境变量 as described in the docs 传递它,但是与令牌似乎比需要的更广泛:
构建过程应该只能访问 Firebase 项目 B
,而不是“我所有的 Firebase 数据和设置”和“我的 Google 云数据”。
- 这里有什么办法可以避免运行
firebase login
吗?似乎服务帐户应该已经有足够的访问权限来部署到 Firebase 托管。
- 如果我需要 运行
firebase login
,有什么方法可以创建一个有限范围的令牌(假设我对默认范围的理解是正确的)?
(我还在 A
中为 B
的服务帐户赋予了 Cloud Functions Developer
角色,并且能够成功 运行 gcloud --project=$_FIREBASE_PROJECT_ID functions deploy ...
不同的构建配置。我还使用类似于上述配置的 Cloud Build 配置部署到同一 GCP 项目中的 Firebase 托管,因此我怀疑 firebase login
在所有情况下都不是必需的。)
我找到了一种方法,可以让项目 A
的 Cloud Build 服务帐户部署到 B
,而无需过多的权限。
首先,我在 B
下创建了一个名为 deploy
的服务帐户,然后 g运行 将其命名为 Firebase Hosting Admin
、Firebase Rules Admin
和 Cloud Datastore Index Admin
角色。 (我不确定是否需要 Datastore 角色,但控制台显示它是最近使用的,所以我保留了它。)
接下来,我为新服务帐户生成了一个 JSON 密钥,将其粘贴(包括换行符和 double-quotes)作为名为 _DEPLOY_CREDENTIALS
的替换变量,并更新了构建步骤将其复制到环境中:
- id: firebase_deploy
name: gcr.io/$PROJECT_ID/firebase
entrypoint: bash
args: ['-e', '--', 'build/deploy_hosting.sh']
env:
- DEPLOY_CREDENTIALS=$_DEPLOY_CREDENTIALS
- FIREBASE_PROJECT_ID=$_FIREBASE_PROJECT_ID
- FIREBASE_HOSTING_TARGET=$_FIREBASE_HOSTING_TARGET
在 deploy_hosting.sh
中,我将凭据写入一个临时文件,然后通过 GOOGLE_APPLICATION_CREDENTIALS
环境变量将它们传递给 firebase
命令:
#!/bin/bash
set -e
CREDS=$(mktemp -t creds.json.XXXXXXXXXX)
printenv DEPLOY_CREDENTIALS >"$CREDS"
export GOOGLE_APPLICATION_CREDENTIALS=$CREDS
firebase --debug use "$FIREBASE_PROJECT_ID"
firebase target:apply hosting prod "$FIREBASE_HOSTING_TARGET"
firebase deploy --project="$FIREBASE_PROJECT_ID" --only=hosting,firestore:rules
我为该步骤创建了一个单独的 shell 脚本,因为我 运行 遇到了在直接从构建步骤编写凭据时从凭据中删除引号的问题。有可能将凭据存储在 Secret Manager 中,但这对我的用例来说有点过分了。
我仍然很好奇是否有办法让 A
的服务帐户部署到 B
而无需在 B
中使用服务帐户而 运行 firebase
可执行文件。
我有 GCP 项目 A
和 Firebase 项目 B
(在单独的 GCP 项目中)。我正在尝试在 A
中使用 Cloud Build 构建 Web 应用程序并将其部署到 B
中的 Firebase 托管。
在 B
的 IAM 页面中,我已授予 A
的 <id>@cloudbuild.gserviceaccount.com
服务帐户 API Keys Admin
、Firebase Admin
和 Service Account User
中描述的角色
A
使用的 Cloud Build 配置的最后一步如下:
- id: firebase_deploy
name: gcr.io/$PROJECT_ID/firebase
entrypoint: sh
args:
- '-c'
- |
firebase use $_FIREBASE_PROJECT_ID
firebase target:apply hosting prod $_FIREBASE_HOSTING_TARGET
firebase deploy --project=$_FIREBASE_PROJECT_ID --only=hosting,firestore:rules
我将 _FIREBASE_PROJECT_ID
替换变量设置为 B
,将 _FIREBASE_HOSTING_TARGET
变量设置为我用于站点的主机别名。
当我触发构建时,它失败并出现以下错误:
...
Step #3 - "firebase_deploy": Error: Invalid project selection, please verify project B exists and you have access.
Step #3 - "firebase_deploy":
Step #3 - "firebase_deploy": Error: Must have an active project to set deploy targets. Try firebase use --add
Step #3 - "firebase_deploy":
Step #3 - "firebase_deploy": Error: Failed to get Firebase project B. Please make sure the project exists and your account has permission to access it.
Finished Step #3 - "firebase_deploy"
我怀疑问题可能出在我没有先 运行 Firebase CLI 的额外登录步骤。为此,我似乎需要在本地 运行 firebase login:ci
生成一个令牌,然后通过 FIREBASE_TOKEN
环境变量 as described in the docs 传递它,但是与令牌似乎比需要的更广泛:
构建过程应该只能访问 Firebase 项目 B
,而不是“我所有的 Firebase 数据和设置”和“我的 Google 云数据”。
- 这里有什么办法可以避免运行
firebase login
吗?似乎服务帐户应该已经有足够的访问权限来部署到 Firebase 托管。 - 如果我需要 运行
firebase login
,有什么方法可以创建一个有限范围的令牌(假设我对默认范围的理解是正确的)?
(我还在 A
中为 B
的服务帐户赋予了 Cloud Functions Developer
角色,并且能够成功 运行 gcloud --project=$_FIREBASE_PROJECT_ID functions deploy ...
不同的构建配置。我还使用类似于上述配置的 Cloud Build 配置部署到同一 GCP 项目中的 Firebase 托管,因此我怀疑 firebase login
在所有情况下都不是必需的。)
我找到了一种方法,可以让项目 A
的 Cloud Build 服务帐户部署到 B
,而无需过多的权限。
首先,我在 B
下创建了一个名为 deploy
的服务帐户,然后 g运行 将其命名为 Firebase Hosting Admin
、Firebase Rules Admin
和 Cloud Datastore Index Admin
角色。 (我不确定是否需要 Datastore 角色,但控制台显示它是最近使用的,所以我保留了它。)
接下来,我为新服务帐户生成了一个 JSON 密钥,将其粘贴(包括换行符和 double-quotes)作为名为 _DEPLOY_CREDENTIALS
的替换变量,并更新了构建步骤将其复制到环境中:
- id: firebase_deploy
name: gcr.io/$PROJECT_ID/firebase
entrypoint: bash
args: ['-e', '--', 'build/deploy_hosting.sh']
env:
- DEPLOY_CREDENTIALS=$_DEPLOY_CREDENTIALS
- FIREBASE_PROJECT_ID=$_FIREBASE_PROJECT_ID
- FIREBASE_HOSTING_TARGET=$_FIREBASE_HOSTING_TARGET
在 deploy_hosting.sh
中,我将凭据写入一个临时文件,然后通过 GOOGLE_APPLICATION_CREDENTIALS
环境变量将它们传递给 firebase
命令:
#!/bin/bash
set -e
CREDS=$(mktemp -t creds.json.XXXXXXXXXX)
printenv DEPLOY_CREDENTIALS >"$CREDS"
export GOOGLE_APPLICATION_CREDENTIALS=$CREDS
firebase --debug use "$FIREBASE_PROJECT_ID"
firebase target:apply hosting prod "$FIREBASE_HOSTING_TARGET"
firebase deploy --project="$FIREBASE_PROJECT_ID" --only=hosting,firestore:rules
我为该步骤创建了一个单独的 shell 脚本,因为我 运行 遇到了在直接从构建步骤编写凭据时从凭据中删除引号的问题。有可能将凭据存储在 Secret Manager 中,但这对我的用例来说有点过分了。
我仍然很好奇是否有办法让 A
的服务帐户部署到 B
而无需在 B
中使用服务帐户而 运行 firebase
可执行文件。