繁体   English   中英

如何授权 Cloud Build 部署到不同项目中的 Firebase Hosting?

[英]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 AdminFirebase AdminService 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 数据和设置”和“我的谷歌云数据”。

  1. 有什么办法可以避免在这里运行firebase login吗? 看起来服务帐户应该已经有足够的访问权限来部署到 Firebase 托管。
  2. 如果我需要运行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 AdminFirebase Rules AdminCloud 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM