@@ -14,7 +14,7 @@ import {
14
14
secretManagerOrigin ,
15
15
} from "../api" ;
16
16
import { Backend , BackendOutputOnlyFields , API_VERSION } from "../gcp/apphosting" ;
17
- import { addServiceAccountToRoles , getIamPolicy } from "../gcp/resourceManager" ;
17
+ import { addServiceAccountToRoles } from "../gcp/resourceManager" ;
18
18
import * as iam from "../gcp/iam" ;
19
19
import { FirebaseError , getErrStatus , getError } from "../error" ;
20
20
import { input , confirm , select , checkbox , search , Choice } from "../prompt" ;
@@ -246,13 +246,12 @@ export async function createGitRepoLink(
246
246
/**
247
247
* Ensures the service account is present the user has permissions to use it by
248
248
* checking the `iam.serviceAccounts.actAs` permission. If the permissions
249
- * check fails, this returns an error. If the permission check fails with a
250
- * "not found" error, this attempts to provision the service account.
249
+ * check fails, this returns an error. Otherwise, it attempts to provision the
250
+ * service account.
251
251
*/
252
252
export async function ensureAppHostingComputeServiceAccount (
253
253
projectId : string ,
254
254
serviceAccount : string | null ,
255
- deployFromSource = false ,
256
255
) : Promise < void > {
257
256
const sa = serviceAccount || defaultComputeServiceAccountEmail ( projectId ) ;
258
257
const name = `projects/${ projectId } /serviceAccounts/${ sa } ` ;
@@ -267,39 +266,14 @@ export async function ensureAppHostingComputeServiceAccount(
267
266
} catch ( err : unknown ) {
268
267
if ( ! ( err instanceof FirebaseError ) ) {
269
268
throw err ;
270
- }
271
- if ( err . status === 404 ) {
272
- await provisionDefaultComputeServiceAccount ( projectId ) ;
273
269
} else if ( err . status === 403 ) {
274
270
throw new FirebaseError (
275
271
`Failed to create backend due to missing delegation permissions for ${ sa } . Make sure you have the iam.serviceAccounts.actAs permission.` ,
276
272
{ original : err } ,
277
273
) ;
278
274
}
279
275
}
280
- // N.B. To deploy from source, the App Hosting Compute Service Account must have
281
- // the storage.objectViewer IAM role. For firebase-tools <= 14.3.0, the CLI does
282
- // not add the objectViewer role, which means all existing customers will need to
283
- // add it before deploying from source.
284
- if ( deployFromSource ) {
285
- const policy = await getIamPolicy ( projectId ) ;
286
- const objectViewerBinding = policy . bindings . find (
287
- ( binding ) => binding . role === "roles/storage.objectViewer" ,
288
- ) ;
289
- if (
290
- ! objectViewerBinding ||
291
- ! objectViewerBinding . members . includes (
292
- `serviceAccount:${ defaultComputeServiceAccountEmail ( projectId ) } ` ,
293
- )
294
- ) {
295
- await addServiceAccountToRoles (
296
- projectId ,
297
- defaultComputeServiceAccountEmail ( projectId ) ,
298
- [ "roles/storage.objectViewer" ] ,
299
- /* skipAccountLookup= */ true ,
300
- ) ;
301
- }
302
- }
276
+ await provisionDefaultComputeServiceAccount ( projectId ) ;
303
277
}
304
278
305
279
/**
@@ -384,17 +358,27 @@ async function provisionDefaultComputeServiceAccount(projectId: string): Promise
384
358
throw err ;
385
359
}
386
360
}
387
- await addServiceAccountToRoles (
388
- projectId ,
389
- defaultComputeServiceAccountEmail ( projectId ) ,
390
- [
391
- "roles/firebaseapphosting.computeRunner" ,
392
- "roles/firebase.sdkAdminServiceAgent" ,
393
- "roles/developerconnect.readTokenAccessor" ,
394
- "roles/storage.objectViewer" ,
395
- ] ,
396
- /* skipAccountLookup= */ true ,
397
- ) ;
361
+ try {
362
+ await addServiceAccountToRoles (
363
+ projectId ,
364
+ defaultComputeServiceAccountEmail ( projectId ) ,
365
+ [
366
+ "roles/firebaseapphosting.computeRunner" ,
367
+ "roles/firebase.sdkAdminServiceAgent" ,
368
+ "roles/developerconnect.readTokenAccessor" ,
369
+ "roles/storage.objectViewer" ,
370
+ ] ,
371
+ /* skipAccountLookup= */ true ,
372
+ ) ;
373
+ } catch ( err : unknown ) {
374
+ if ( getErrStatus ( err ) === 400 ) {
375
+ logWarning (
376
+ "Your App Hosting compute service account is still being provisioned in the background; you may continue with the init flow." ,
377
+ ) ;
378
+ } else {
379
+ throw err ;
380
+ }
381
+ }
398
382
}
399
383
400
384
/**
0 commit comments