Build process overview

This guide shows the build process overview for functions that were deployed using the gcloud functions command. To learn the build process for functions deployed using the gcloud run command, see:

When you deploy your function's source code using the gcloud functions deploy command, that source is stored in a Cloud Storage bucket. Cloud Build then automatically builds your code into a container image and pushes that image to an image registry.

The process of building the image is entirely automatic and requires no direct input from you. All the resources used in the build process execute in your own user project.

Executing the build process within your project means that:

  • You have direct access to all build logs.

  • There is no preset build-time quota, although Cloud Build does have its own default concurrency quota.

  • You can view the current container image and the previously deployed container images, both of which are stored in Artifact Registry.

  • Cloud Storage is used in your project to store the source code directory for your functions. Note the following:

    • If you create a function using the Google Cloud CLI, an upload bucket is created to hold your source code. This upload bucket might be named gcf-v2-uploads-PROJECT_NUMBER-REGION.cloudfunctions.appspot.com.
    • After the code is uploaded, function code is stored in a separate source bucket:
      • If you're using default encryption, this bucket is named gcf-v2-sources-PROJECT_NUMBER-REGION.
      • If you're protecting your data with CMEK, the bucket is named gcf-v2-sources-PROJECT_NUMBER-REGION-CMEK_KEY_HASH.
    • Both source and upload buckets have no retention period.

Characteristics of the build process

The build process has the following characteristics:

  • The Cloud Build API must be enabled for your project.

    To enable the API manually, click the earlier link, select your project from the drop-down menu, and follow the prompts to enable the UI.

  • Because the entire build process takes place within the context of your project, the project is subject to the pricing of the included resources:

    • For Cloud Build pricing, see the Pricing page. This process uses the default instance size of Cloud Build, as these instances are pre-warmed and are available more quickly. Cloud Build does provide a free tier: review the pricing document for further details.

    • For Cloud Storage pricing, see the Pricing page. Cloud Storage does provide a free tier: review the pricing document for further details.

    • For Artifact Registry pricing, see the Pricing page.

  • Because the build process is subject to billing, your project must have a Cloud Billing Account attached to it.

View your build image logs

A key benefit of having the build image process in your user project is access to build logs. You can use gcloud CLI or the Google Cloud console to reach the logs, which are available through Cloud Logging.

gcloud

  1. Deploy your function using the gcloud functions deploy command.

  2. The URL of the logs is shown as part of the response in your terminal window. For example:

    Deploying function (may take a while - up to 2 minutes)...⠹
    **For Cloud Build Stackdriver Logs**, visit:
    https://console.cloud.google.com/logs/viewer?project=&advancedFilter=resource.type%
    3Dbuild%0Aresource.labels.build_id%3D38d5b662-2315-45dd-8aa2-
    380d50d4f5e8%0AlogName%3Dprojects%2F%
    2Flogs%2Fcloudbuild
    Deploying function (may take a while - up to 2 minutes)...done.

Google Cloud console

To view function logs in the Cloud Run page:

  1. Go to Cloud Run

  2. Click the chosen function in the displayed list.

  3. Click the LOGS tab to get the request and container logs for all revisions of this function. You can filter by log severity level.

Image registry

Artifact Registry is used to store the images built from your function source code. Images are stored in a repository named REGION-docker.pkg.dev/PROJECT_ID/gcf-artifacts located in the same project where your function is created.

To specify a self-managed Artifact Registry repository, run the following command:

gcloud functions deploy FUNCTION_NAME \
   --docker-repository=REPOSITORY \
   [FLAGS...]

Replace the following:

  • FUNCTION_NAME: The name of the function.
  • REPOSITORY: The fully qualified Artifact Registry repository name, in the following format: projects/PROJECT_NAME/locations/LOCATION/repositories/REPOSITORY.

When specifying a Artifact Registry repository located in a different project or region you may need to consider additional configurations:

IAM configurations:

  • IAM configurations: Ensure that the build service account has authorized access to read and write to the REPOSITORY.
  • Network configurations: Ensure that the target REPOSITORY is reachable from the current project configuration.
  • VPC Service Controls configurations: Ensure that the build service account can reach the target REPOSITORY within the VPC-SC perimeter.
  • Data residency constraints: Specifying a REPOSITORY in a different region from where your function is located will lead to data transfer across regions.

Secure your build with private pools

To allow your functions to use dependencies (for example, npm packages), Cloud Build has by default unlimited internet access during the build process. If you have set up a VPC Service Controls (VPC SC) perimeter and want to limit the build's access only to dependencies stored inside the perimeter, you can use the Cloud Build private worker pools feature.

In general, follow these steps to set up your private pool:

  1. Create your private worker pool. See Create and manage private pools.
  2. Configure your VPC Service Controls perimeter. See Using VPC Service Controls.

  3. If your private worker pool is in a different project than your function, you need to grant the Cloud Functions Service Agent Service Account (service-FUNCTION_PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com) the cloudbuild.workerPoolUser role so that the Cloud Build service can access the worker pool.

    gcloud projects add-iam-policy-binding PRIVATE_POOL_PROJECT_ID \
        --member serviceAccount:service-FUNCTION_PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com
        --role roles/cloudbuild.workerPoolUser

    Replace FUNCTION_PROJECT_NUMBER with the number of the project where the function runs and PRIVATE_POOL_PROJECT_ID with the ID of the project in which the worker pool is located. See Running builds in a private pool for more information.

  4. Deploy your function to build using a private pool:

    gcloud functions deploy FUNCTION_NAME \
       --runtime RUNTIME \
       --build-worker-pool PRIVATE_POOL_NAME
       [FLAGS...]

    Replace FUNCTION_NAME with the name of the function, RUNTIME with the runtime you are using, and PRIVATE_POOL_NAME with the name of your pool.

To stop using a given private pool and instead use the default Cloud Build pool, use the --clear-build-worker-pool flag when re-deploying.

gcloud functions deploy FUNCTION_NAME \
   --runtime RUNTIME \
   --clear-build-worker-pool
   [FLAGS...]

Replace FUNCTION_NAME with the name of the function and RUNTIME with the runtime you are using.

Secure your build with a custom service account

Your function's source code is sent to Cloud Build to be containerized. The containerized function is stored in Artifact Registry and deployed to Cloud Run as a service. Cloud Run functions leverages Cloud Build when building and deploying your Cloud Run function. By default, Cloud Run functions uses the default Cloud Build service account as the principal when performing your build. Starting in July 2024, Cloud Build changed the default behavior for how Cloud Build uses service accounts in new projects. As a result of this change, new projects deploying functions for the first time may be using a default Cloud Build service account with insufficient permissions for building a function.

For Google Cloud projects created before July 2024, Cloud Build uses the legacy Cloud Build service account. This service account was designed to help users execute a broad range of use cases that may be too permissive for your project's needs. If you want to move your existing projects away from this service account, you can take the following steps to further secure your functions build environment:

Prevent the legacy Cloud Build service account from being used for build

You can verify that your project is using the legacy Cloud Build service account by inspecting the details of your function's build. The default build service account has the following format:

PROJECT_NUMBER@cloudbuild.gserviceaccount.com.

You can forcibly disable use of this service account by setting the org policy constraint cloudbuild.useBuildServiceAccount to Not Enforced. Alternatively, removing all of its role grants will limit its ability to access Google Cloud resources.

Prevent the default compute service account from being used for build

The default compute service account has the format PROJECT_NUMBER-compute@developer.gserviceaccount.com. You can disable it from being the default used for the build by setting the org policy cloudbuild.useComputeServiceAccount to Not Enforced. Alternatively, disabling this service account prevents it from being used to access Google Cloud resources.

Provide a service account for building functions

As part of a function's configuration, you can specify a build service account when deploying the function. When the legacy Cloud Build service account and the default compute service account are prevented from being used for build, you must specify a build service account in order to deploy a function, as described in this section.

If you are impacted by the changes described in Cloud Build Service Account Change, you can do one of the following:

  • Review the Cloud Build guidance on changes to the default service account and opt out of these changes.

  • Add the Cloud Build Account role (roles/cloudbuild.builds.builder) to the default Compute Engine service account.

  • Create a custom Cloud Build service account for function deployments.

Here are some scenarios where you may want to provide a different service account to be used when Cloud Build builds your function:

  • You want more control of which service accounts to add to your VPC-SC perimeter.

  • You want Cloud Build to run with different permissions than what the default service account has without having to revoke each permission individually.

  • You want to set granular Cloud Build permissions specifically for your functions, not share a Cloud Build service account that is optimized for other purposes.

  • Your organization disabled the usage of the default service account.

The following sections show how to create a custom Cloud Build service account for function deployments.

Create a service account

Create a new service account as described in Create a service account.

Grant Permissions

The service account you use will need the following roles:

  • roles/logging.logWriter— Required to store build logs in Cloud Logging.
  • roles/artifactregistry.writer— Required to store build images in Artifact Registry. For the default behavior, the service account needs access to repositories named "gcf-artifacts" and "cloud-run-source-deploy". Access to the repositories can be set on the repository's IAM policy. You can alternatively provide your own artifact repository through dockerRepository field.
  • roles/storage.objectViewer— Required to retrieve the function source from the Cloud Storage bucket, and to store build images in Container Registry. For the default behavior, the service account needs access to buckets named "run-sources-*", "gcf-v2-sources-*" and "gcf-v2-uploads-*". This can be accomplished by adding an IAM condition to the role grant such as: (resource.type == "storage.googleapis.com/Object" && (resource.name.startsWith("gcf-v2-sources-") || resource.name.startsWith("gcf-v2-uploads-") || resource.name.startsWith("run-sources-")))

Grant the following roles using the Google Cloud CLI, or use Google Cloud console.

gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SA_EMAIL \
    --role=roles/logging.logWriter

gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SA_EMAIL \
--role=roles/artifactregistry.writer

gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SA_EMAIL \
--role=roles/storage.objectViewer

Replace the following:

VPC Service Controls considerations

If you have a VPC Service Controls perimeter protecting both your project and the Cloud Run functions API, and if you're using the Compute Engine default service account as the Cloud Build Service Account role for Cloud Run functions, you must create the following ingress rules:

  • Allow Compute Engine default service account ingress to all methods on both Cloud Storage and Cloud Logging APIs.
  • Allow the service account service-[PROJECT_NUMBER]@gcf-admin-robot.iam.gserviceaccount.com ingress to all methods on both Cloud Storage and Cloud Logging APIs.

Deploy a function with a custom service account

To pass in a user-created service account, to be used by Cloud Build, when deploying your function, run the following gcloud command:

  • The --build-service-account flag specifies an IAM service account whose credentials will be used for the build step. If a custom service account is not provided, the function uses the project's default service account for Cloud Build.
  • You can optionally use a private pool, which you specify using the --build-worker-pool flag.

gcloud functions deploy FUNCTION_NAME \
   --gen2 \
   --region=REGION \
   --project=PROJECT_ID \
   --runtime=RUNTIME \
   --entry-point=CODE_ENTRYPOINT \
   --build-service-account=projects/PROJECT_ID/serviceAccounts/SA_EMAIL \
   --memory=256Mi \
   --trigger-http \
   --source=.

Replace the following:

  • FUNCTION_NAME: The name under which you deployed your function.
  • REGION: The name of the Google Cloud region where you want to deploy your function (for example, us-west1).
  • PROJECT_ID: Your Google Cloud project ID.
  • RUNTIME: The runtime ID of a supported runtime version to run your function, for example, nodejs18.
  • CODE_ENTRYPOINT: The entry point to your function in your source code. This is the code that will be executed when your function runs.
  • SA_EMAIL: The email address of your service account.