Prepare and test your skills
Prepare and test your skills
A Version Control System (VCS) trigger is an automation rule in Cloud Build (opens in a new tab) that starts a build when a repository event occurs. The trigger connects to a repository on GitHub, GitHub Enterprise, Bitbucket Cloud (opens in a new tab), or Cloud Source Repositories, checks the event against branch, tag, and pull request filters, and runs the selected build configuration under a designated service account. This design lets one repository drive different pipelines for development branches, release tags, and proposed changes without manual invocation.
VCS trigger events define which repository activity flows from the connected repository to Cloud Build to start a build. Each trigger listens for one event type, and a build starts only when the event type matches and the branch or tag filter also matches. Choosing the event controls whether continuous integration runs on every commit, only on releases, or only on code review activity.
| Event | Starts when | Choose when |
|---|---|---|
| Push to a branch | Commits are pushed to a matching branch | Continuous builds and tests are needed for each change on development or main branches |
| Push new tag | A push contains a matching tag | Release, packaging, or deployment builds should run only for tagged versions |
| Pull request | Commits are pushed to a pull request or merge request | Validation, testing, and approval-gated builds are needed before merging |
The filter acts as the control boundary between the external repository and the build environment, so only matching events cross into Cloud Build execution.
Branch and tag matching controls which pushes invoke a VCS trigger by comparing the branch or tag name against a pattern. Automated triggers use BRANCH_PATTERN and TAG_PATTERN values that are regular expressions, so one trigger can match main, release-.*, or v2\..* without creating a separate trigger for each name. The build starts only when both the event type and the regular expression match the push.
Manual triggers (opens in a new tab) behave differently because a manual trigger requires a literal branch or tag value and does not accept regular expressions. A manual trigger can also target a specific commit by SHA in addition to a branch or tag. This distinction keeps automated triggers flexible for pattern-based continuous integration while keeping manual invocations pinned to an exact source version.
Exam tip: Automated VCS triggers accept regular expressions for branch and tag filters, while manual triggers for Cloud Build repositories require a literal branch, tag, or SHA value.
The trigger source defines the repository connection, the region boundary, and the identity that Cloud Build uses to fetch code and run operations. Second-generation triggers use Cloud Build repositories through a Developer Connect host connection, and the region of the repository must match the region of the trigger. The trigger runs under a specified service account, or under the default Cloud Build service account when none is specified, and that account becomes the identity for trigger and build operations.
Region selection also determines where the build executes and whether isolation is required. If the build configuration specifies a private pool, Cloud Build runs the build in that private pool and the trigger region must match the private pool region. If the build configuration does not specify a private pool, Cloud Build runs the build in the default pool in the same region as the trigger.
The build configuration defines what Cloud Build executes after a VCS trigger fires. The configuration can live in the remote repository or be defined inline in the trigger, and the source checkout supplied to the build is a shallow clone containing only the single commit that started the build. The shallow clone keeps fetches fast but omits other branches and history.
Three configuration options cover the common build styles:
cloudbuild.yaml or cloudbuild.json file stored at BUILD_CONFIG_FILE in the repository, or supply the same YAML or JSON content inline through the console or --inline-config.Dockerfile for the configuration by supplying the Dockerfile directory, the resulting image name, and optionally a build timeout, which produces a docker build style execution.Two optional controls affect visibility and security for Git-based sources. The --require-approval flag gates builds on manual approval before execution, and --include-logs-with-status shows build logs with repository status for GitHub and GitHub Enterprise triggers created with gcloud. The logs flag is not supported for creating triggers in the Google Cloud console.
Manual testing, skipping, and approval control manage the lifecycle of a VCS trigger from creation through execution. A newly created trigger name is automatically generated when created with gcloud and can be renamed in the console, and event filtering can take time to propagate before the first automatic invocation. These controls let operators verify the trigger, suppress unwanted builds, and re-run gated builds without changing the filter definition.
The lifecycle controls run in this order:
[skip ci] or [ci skip] in the commit message to prevent the push from invoking a build, such as for documentation-only changes, and use Run later if that commit still needs a build.Builds that need more than the triggering commit must explicitly expand history because shallow clones omit history for efficiency. Add a build step that runs git fetch --unshallow with the gcr.io/cloud-builders/git builder to fetch full history into the workspace. When the source is a private Git repository, store credentials securely in Secret Manager so the fetch step can authenticate to the external source code management system.
Webhook and event-driven triggers are automated Cloud Build (opens in a new tab) triggers that start a build when an external event occurs rather than waiting for manual submission. A trigger listens for a defined event, such as a push to source or a data-arrival signal, and then executes the configured build steps defined in a build configuration file. This model enables secure, efficient continuous integration and deployment across GitHub, Bitbucket, Artifact Registry, and data-driven sources.
Automated triggers in Cloud Build are rules that import source and execute a build as a series of build steps defined in cloudbuild.yaml. Each build step runs in a Docker container, and the process can start manually through the CLI or API or automatically through automated build triggers. An automated trigger executes its configured build steps whenever changes reach the build source, or only when changes match criteria such as branch, tag, or file pattern. You can maintain different build routines for different triggers, for example one routine that runs when commits reach the development branch and another routine that runs when commits reach the main branch.
Trigger filtering keeps event-driven pipelines efficient by preventing unnecessary builds. A single repository can therefore fan out to multiple cloudbuild.yaml routines, where each routine depends on its own trigger condition. The trigger condition acts as the trust and control boundary because only events that satisfy the filter cross from the external system into the build environment. You can also configure the pipeline to skip triggers for low-risk changes, such as edits to only documentation files or experimentation notebooks.
Substitution variables in Cloud Build are build-time environment variables that let one build definition behave dynamically for different triggering events. Substitutions are captured from triggered builds and are useful for values that are not known until build time or to reuse an existing build request with different variable values. Incoming event metadata maps directly into these variables, so the same cloudbuild.yaml can tag, route, and record artifacts differently for each invocation.
Triggered builds provide event-specific substitutions:
$COMMIT_SHA identifies the commit that caused the trigger$REPO_NAME identifies the source repository$BRANCH_NAME identifies the triggering branch$TAG_NAME identifies the triggering tag$REVISION_ID identifies the source revisionOther substitutions are not trigger-based, including $PROJECT_ID and $BUILD_ID. A common dynamic pattern is tagging built container images with $COMMIT_SHA, which links each image in Artifact Registry back to the exact source event that produced it.
Exam tip: $COMMIT_SHA, $REPO_NAME, $BRANCH_NAME, $TAG_NAME, and $REVISION_ID are captured from triggered builds, while $PROJECT_ID and $BUILD_ID are available outside triggers.
Event sources beyond source push are data and operational signals that start machine learning and data workflows through Cloud Build. A larger workflow, such as a data ingestion workflow, can trigger a training pipeline after BigQuery ingests new data, so model retraining flows from the data-arrival event to the pipeline execution. Cloud Logging can also publish a message when logs meet filter criteria, and those filters can detect the arrival of new data or skew and drift alerts from model monitoring. In this flow, the monitored system is the source, the log filter is the event detector, and the downstream build or pipeline run is the destination.
Once invoked, the triggered Cloud Build workflow typically moves source and artifacts through an ordered sequence:
/workspace directory.$COMMIT_SHA.pipeline.json file.pipeline.json file is uploaded to Artifact Registry.This sequence shows why substitution mapping matters because the value captured at trigger time in step 1 controls tagging in step 4, traceability in steps 5 through 8, and which artifact is executed in step 9.
Secure trigger execution is the practice of running automated continuous integration and continuous delivery (CI/CD) builds under a dedicated identity with only the permissions the build needs. In Google Cloud, Cloud Build (opens in a new tab) runs builds on Google Cloud infrastructure when a trigger fires on a source change, and Identity and Access Management (IAM) controls which service account the trigger uses and what that account can access. By assigning a user-specified service account to each trigger, teams replace broad default identities with isolated, least-privilege execution that limits blast radius across projects and tenants.
A user-specified service account for triggers is a customer-created identity that Cloud Build impersonates when a trigger executes its configured build steps. The trigger flow moves from the source event to the build runtime to Google Cloud resources: a push or pull request fires the trigger, the trigger starts the build under the assigned service account, and that account reads source, writes artifacts, and calls deployment services. By default, builds may rely on the Cloud Build service account (PROJECT_NUMBER@cloudbuild.gserviceaccount.com) and the Compute Engine default service account (PROJECT_NUMBER-compute@developer.gserviceaccount.com), where the Compute Engine default service account usually has a broader set of permissions than production jobs require. Production guidance is to specify a user-managed account instead, for example with the --serviceAccount pipeline option for Dataflow (opens in a new tab) jobs, and to apply the same pattern to Cloud Build triggers so each pipeline, branch, or tenant has its own execution identity.
Separation of management identity from runtime identity further hardens trigger execution. In production scenarios, teams use one service account to create and manage jobs and a different worker service account to run the workload and touch data sources, sinks, Compute Engine resources, and the build service. The job-management account therefore does not need access to data or pipeline resources, while the worker account does not need permission to create jobs or modify pipeline configuration. This split means a compromise of build orchestration does not automatically grant data access, and a compromise of the worker does not automatically grant control-plane control.
Least-privilege design for triggers means granting the trigger service account only the minimum IAM permissions required for its build steps and nothing more. Role-based access control (RBAC) implements this by mapping IAM roles to the trigger service account based on project needs, access patterns, or tags, so a training pipeline account might read from only one Cloud Storage bucket and write model artifacts only to Model Registry. Over-granting commonly happens by granting access at the project level instead of the resource level, or by assigning an overly permissive role such as full storage access when only bucket creation or single-bucket read and write is needed. Because a deployment pipeline must maintain confidentiality and integrity, it must not read data it does not need and must not write to network or storage locations it does not need, which directly reduces direct exfiltration and indirect exfiltration through compromised code.
Granular IAM controls refine least privilege beyond basic roles:
Exam tip: Granting the Service Account User role (roles/iam.serviceAccountUser) on a service account lets the grantee act as that account, indirectly gaining its permissions — if the target is a highly privileged default account, the grantee effectively gains those privileges.
Isolation across environments means each deployment environment and tenant gets unique credentials and a tightly scoped trust boundary. Where possible, teams use unique service accounts for each project to read and write deployment artifacts, stage templates, and manage resources within that project only. The build and deployment infrastructure sits inside controls such as Virtual Private Cloud (VPC) networks, VPC Service Controls perimeters, and isolated and ephemeral build environments, so traffic flows from the trigger to the build workers to the target project without crossing into other tenants. Restricting outbound access is especially important for pipelines that handle confidential data or cryptographic key material, by revoking unneeded write access and blocking internet access or restricting connections to an allow-listed set of locations.
The following comparison summarizes the identity choice for trigger and job execution:
| Identity option | Default scope | Security posture |
|---|---|---|
| Cloud Build service account | Project-level build execution as PROJECT_NUMBER@cloudbuild.gserviceaccount.com | Requires added roles such as Workflows Admin for deployment; shared across triggers unless replaced |
| Compute Engine default service account | Project-wide compute identity as PROJECT_NUMBER-compute@developer.gserviceaccount.com | Usually broader than required; avoid for production workloads |
| User-specified service account | Dedicated, per-trigger or per-environment identity with resource-level grants | Least privilege and tenant isolation; separate management and worker accounts when possible |
To keep scope small when triggers span development, staging, and production, limit each pipeline to a relatively small number of resources. Instead of granting access at the project level, grant access to individual resources, avoid granting access across multiple Google Cloud projects from one pipeline, and split multi-project or multi-environment pipelines into multiple stages that are secured individually.
IAM roles for trigger configuration separate who can create triggers from what triggers can do when they run. Creating and editing triggers requires the Cloud Build Editor role (roles/cloudbuild.builds.editor), while the Cloud Build service account itself needs target-service roles such as the Workflows Admin role (roles/workflows.admin) to deploy workflows. When the build must act as another runtime identity, the build service account needs the Service Account User role (roles/iam.serviceAccountUser) on that runtime account, configured according to the principle of least privilege because the role confers act-as power. These layers create an ordered dependency: the human or automation creator depends on trigger-management permission, the trigger depends on its assigned service account, and the service account depends on narrowly scoped resource permissions plus any IAM Conditions that bind invocation to a trusted source.
Approval and audit controls complete secure trigger execution for high-integrity environments. If an attacker compromises the CI/CD pipeline, the entire application stack can be affected, so production promotion uses an established approval process, vulnerability scanning with Artifact Analysis, and verifiable build provenance including Supply chain Levels for Software Artifacts (SLSA) build level, artifact digests, source locations, toolchain, steps, and duration. Binary Authorization attestations can then verify that a specific build system created an image, that the image meets vulnerability policy, and that it passed promotion criteria before Google Kubernetes Engine or Cloud Run admits it. Together, dedicated trigger identities, least-privilege IAM, environment isolation, and attested promotion ensure that automation removes manual error without giving every code change the keys to production.
BRANCH_PATTERN and TAG_PATTERN to match branches and tags, while manual triggers require a literal branch, tag, or commit SHA.$COMMIT_SHA, $REPO_NAME, $BRANCH_NAME, $TAG_NAME, and $REVISION_ID.roles/cloudbuild.builds.editor, and allowing a build to act as another identity requires roles/iam.serviceAccountUser on that runtime account.Use push to a branch for continuous builds and tests on each change, push new tag for release, packaging, or deployment builds for tagged versions, and pull request for validation, testing, and approval-gated builds before merging. Each trigger listens for one event type and a build starts only when the event type and the branch or tag filter both match.
Automated Version Control System (VCS) triggers match branches and tags with regular expressions in BRANCH_PATTERN and TAG_PATTERN, while manual triggers require a literal branch or tag value. A manual trigger can also target a specific commit by SHA in addition to a branch or tag.
Creating and editing Cloud Build triggers requires the Cloud Build Editor role (roles/cloudbuild.builds.editor), while allowing a build to act as another runtime identity requires the Service Account User role (roles/iam.serviceAccountUser) on that runtime account. The Service Account User role confers act-as power and should be configured according to the principle of least privilege.
Your DevOps engineering team is configuring an automated continuous integration pipeline using Cloud Build for an application repository hosted on GitLab.
You must configure a Cloud Build trigger that meets the following criteria:
release/v1.0 or release/v2.4./gcbrun comment command before a build executes.How should you configure the Cloud Build trigger?
Last updated