[英]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
环境变量传递它,但与令牌关联的权限似乎比需要的要广泛得多:
构建过程应该只能访问 Firebase 项目B
,而不是“我所有的 Firebase 数据和设置”和“我的谷歌云数据”。
firebase login
吗? 看起来服务帐户应该已经有足够的访问权限来部署到 Firebase 托管。firebase login
,有没有办法创建一个限制为 scope 的令牌(假设我对默认 scope 的理解是正确的)? (我还为B
的服务帐户授予了A
中的Cloud Functions Developer
角色,并且能够在不同的构建配置中成功运行gcloud --project=$_FIREBASE_PROJECT_ID functions deploy...
我也在使用 Cloud Build配置类似于上述配置以部署到同一 GCP 项目中的 Firebase 托管,因此我怀疑在所有情况下都不需要firebase login
。)
我找到了一种方法,可以让项目A
的 Cloud Build 服务帐户部署到B
而无需过多的权限。
首先,我在B
下创建了一个名为deploy
的服务帐户,并授予它Firebase Hosting Admin
、 Firebase Rules Admin
和Cloud Datastore Index Admin
角色。 (我不确定是否需要 Datastore 角色,但控制台显示它最近正在使用,所以我离开了它。)
接下来,我为新服务帐户生成了一个 JSON 密钥,将其粘贴(包括换行符和双引号)作为名为_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
而无需在运行firebase
可执行文件时使用B
中的服务帐户。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.