您可以使用 gcloud CLI、Terraform 或 Go 等用戶端程式庫,透過程式輔助方式設定及提交 Image Builder 管道。透過程式輔助方式設定管道,即可在宣告式設定檔中定義基礎架構設定、基本 OS 映像檔、自訂動作和驗證測試。
事前準備
- 完成「準備環境」中的環境設定步驟。
- 如果您打算使用 Terraform 部署管道,或從存放區自動建構,請使用 Cloud Build 存放區 (
2nd gen) 或 Developer Connect 連線連結,連結 GitHub、GitLab 或 Bitbucket 存放區。 - 如要使用 Terraform,請安裝 Terraform CLI 1.3 以上版本。
-
如果尚未設定驗證,請先完成設定。驗證程序會確認您的身分,以便授予 Cloud de Confiance by S3NS 服務和 API 的存取權。如要從本機開發環境執行程式碼或範例,您可以選取下列其中一個選項,向 Compute Engine 進行驗證:
請根據您打算如何使用本頁範例,選取對應的分頁標籤:
gcloud
-
安裝 Google Cloud CLI,然後 使用聯合身分登入 gcloud CLI。 登入後,執行下列指令來初始化 Google Cloud CLI:
gcloud init
-
- 設定預設區域和可用區。
-
安裝 Google Cloud CLI。
-
設定 gcloud CLI,使用您的聯合身分。
詳情請參閱「 使用聯合身分登入 gcloud CLI」。
-
為使用者帳戶建立本機驗證憑證:
gcloud auth application-default login
如果傳回驗證錯誤,請確認您已 使用聯合身分登入 gcloud CLI。
-
安裝 Google Cloud CLI。
-
設定 gcloud CLI,使用您的聯合身分。
詳情請參閱「 使用聯合身分登入 gcloud CLI」。
-
為使用者帳戶建立本機驗證憑證:
gcloud auth application-default login
如果傳回驗證錯誤,請確認您已 使用聯合身分登入 gcloud CLI。
Terraform
如要在本機開發環境中使用本頁的 Terraform 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。
詳情請參閱「 為本機開發環境設定驗證機制」。
Go
如要在本機開發環境中使用本頁面的 Go 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。
詳情請參閱「 為本機開發環境設定驗證機制」。
必要的角色
如要取得透過程式建立及提交圖片自訂管道所需的權限,請要求管理員在專案中授予您下列 IAM 角色:
- Cloud Build 編輯者 (
roles/cloudbuild.builds.editor) - 服務帳戶使用者 (
roles/iam.serviceAccountUser)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。
建立設定檔
如要使用 gcloud CLI 或 Terraform 設定管道,請建立兩個設定檔:
imagebuilder.yaml:定義映像檔的自訂配方,包括基礎 OS 映像檔、worker VM 基礎架構設定、目標映像檔輸出詳細資料,以及依序執行的自訂步驟,例如執行殼層指令碼、傳輸檔案或重新啟動。cloudbuild.yaml:在 Cloud Build 中自動調度建構程序步驟,包括剖析、驗證、建構、測試及發布自訂 OS 映像檔。
如果您使用 Go 提交建構作業,則只需建立 imagebuilder.yaml 檔案並上傳至 Cloud Storage bucket,因為 Go 範例會在程式碼中定義 Cloud Build 協調步驟。
建立映像檔設定檔
如要指定映像檔設定,請在本機目錄中建立名為 imagebuilder.yaml 的檔案。如需所有支援的結構定義欄位和自訂動作完整清單,請參閱「自訂配方結構定義」和「支援的自訂動作」。
下列 imagebuilder.yaml 檔案範例會設定管道,使用指定區域和可用區中的 e2-standard-4 worker VM 建構自訂 Ubuntu 22.04 LTS 映像檔,並執行系統套件更新。
apiVersion: imagebuilder.gcp.com/v1 kind: OSImageCustomization metadata: name: customized-ubuntu-baseline description: "Ubuntu 22.04 LTS custom OS baseline image" infrastructureConfig: machineType: e2-standard-4 zone: ZONE debug: false source: imageFamily: projects/ubuntu-os-cloud/global/images/family/ubuntu-2204-lts destinations: - diskImage: name: custom-ubuntu-v1 family: custom-ubuntu-family project: PROJECT_ID storageLocations: - REGION spec: config: skipSystemTests: false steps: - name: "System Package Update" action: Shell inputs: command: "apt-get update -y && apt-get upgrade -y"
替換下列預留位置值:
PROJECT_ID:您的專案 ID。REGION:目標映像檔儲存位置,例如us-east1或europe-west1。請確認您符合下列區域和可用區規定:- Image Builder 僅適用於支援 Cloud Build 的區域。
- worker VM
ZONE必須位於您指定的REGION內。 - 為盡可能縮短網路延遲時間,並避免產生跨區域輸出費用,請確保 worker VM 可用區、Cloud Storage 暫存 bucket、Artifact Registry 存放區和目標映像檔儲存位置都位於相同區域。
ZONE:位於指定REGION內的可用區,例如us-east1-b或europe-west1-b。
建立自動調度管理工具建構檔案
在同一個目錄中建立名為 cloudbuild.yaml 的檔案。這個檔案會呼叫 Image Builder 容器步驟,建構、驗證及發布自訂 OS 映像檔。
substitutions: _GCS_WORKDIR: 'gs://STAGING_BUCKET_NAME/workdir/' _IMAGE_BUILDER_CONFIG_PATH: 'imagebuilder.yaml' _SERVICE_ACCOUNT: 'projects/PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT_EMAIL' _IMAGE_OUTPUT_PATH: 'image-builder/binaryOut' _ARTIFACT_REGISTRY_RESOURCE_URI: 'projects/PROJECT_ID/locations/REGION/repositories/REPOSITORY_NAME/packages/PACKAGE_NAME/versions/v${BUILD_ID}' steps: # Step 1: Parse configs and run OS customization on worker VM - name: 'REGION-docker.pkg.dev/image-builder-official/release/builder:stable' script: | #!/usr/bin/env bash /build id: 'imagebuilder-customize' results: - name: image_builder_telemetry_metrics - name: base_image attestationType: "https://cloudbuild.googleapis.com/attestations/build_content_restrictions" attestationContent: base_image # Step 2: Validate by running system boot checks on a test VM - name: 'REGION-docker.pkg.dev/image-builder-official/release/validator:stable' script: | #!/usr/bin/env bash /validate id: 'imagebuilder-validate' results: - name: image_builder_telemetry_metrics # Step 3: Register image in Compute Engine and upload tar files to Artifact Registry - name: 'REGION-docker.pkg.dev/image-builder-official/release/builder:stable' script: | #!/usr/bin/env bash /publish id: 'imagebuilder-publish' results: - name: image_builder_telemetry_metrics options: automapSubstitutions: true requestedVerifyOption: VERIFIED substitutionOption: ALLOW_LOOSE dynamicSubstitutions: true logging: CLOUD_LOGGING_ONLY artifacts: generic_artifacts: - folder: '${_IMAGE_OUTPUT_PATH}' registry_path: '${_ARTIFACT_REGISTRY_RESOURCE_URI}' timeout: '3600s'
替換下列預留位置值:
STAGING_BUCKET_NAME:專案中現有的 Cloud Storage bucket,用來做為臨時暫存工作區。如果沒有 bucket,可以執行gcloud storage buckets create gs://STAGING_BUCKET_NAME來建立。如果您使用 Terraform 部署管道,Terraform 會自動建立這個 bucket。PROJECT_ID:您的 Cloud de Confiance 專案 ID。REGION:Artifact Registry 存放區的 Cloud de Confiance 區域,例如us-east1或europe-west1。SERVICE_ACCOUNT_EMAIL:已設定必要 IAM 權限的服務帳戶電子郵件地址。REPOSITORY和PACKAGE:在 Artifact Registry 中建立的目標存放區和套件名稱。如要設定 Artifact Registry 存放區,請參閱「設定 Artifact Registry」。
建立並提交建構管道
如要執行圖片自訂管道,請使用 gcloud CLI 提交建構作業、使用 Terraform 部署管道,或使用 Go 用戶端程式庫提交建構作業。選取下列其中一個分頁:
gcloud
如要部署及執行映像檔自訂 pipeline,請在本機終端機目錄中,執行 gcloud builds submit 指令,該目錄應包含兩個設定檔:
gcloud builds submit . \
--config=cloudbuild.yaml \
--project=PROJECT_ID \
--service-account="projects/PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT_EMAIL" \
--region=REGION
更改下列內容:
PROJECT_ID:您的 Cloud de Confiance 專案 ID。REGION:執行映像檔自訂管道工作的 Cloud de Confiance 區域。SERVICE_ACCOUNT_EMAIL:服務帳戶的電子郵件地址,該帳戶已設定必要的 IAM 權限。
這個指令會上傳自訂工作區、註冊 Cloud Build 執行作業,並啟動自動化調度管理容器。
Terraform
如要佈建自動建構及驗證自訂 OS 映像檔所需的基礎架構,可以使用 Terraform。這項 Terraform 設定會完成下列工作:
- 啟用必要的 Cloud de Confiance API。
- 建立專屬 Cloud Storage bucket (
workdir_bucket),用於儲存臨時記錄和建構構件。 - 設定連結至 Developer Connect GitHub 存放區連線的 Cloud Build 自動建構觸發條件 (
image_builder_trigger)。
建立 Terraform 設定檔
如要使用 Terraform 整理及部署管道基礎架構,請完成下列步驟:
在本機工作站或 CI/CD 環境中,建立與應用程式存放區分開的專屬目錄,然後切換至該目錄:
mkdir terraform-image-builder && cd terraform-image-builder
在這個目錄中,建立下列五個 Terraform 設定檔:
terraform.tfvars:設定專案專屬變數的值。main.tf:在 Cloud de Confiance 專案中佈建資源,包括啟用必要的 API、建立 Cloud Storage 暫存 bucket (workdir_bucket),以及部署 Cloud Build 自動建構觸發條件 (image_builder_trigger)。outputs.tf:定義部署後顯示在終端機的輸出值,例如觸發條件 ID 和暫存 bucket 名稱。providers.tf:指定必要的 Terraform 版本 (>= 1.3),並設定 Cloud de Confiance by S3NS 供應商 (hashicorp/google)。variables.tf:定義部署作業的輸入變數、預設值和驗證規則。
選取下列其中一個分頁標籤,即可查看各檔案的設定,並複製到本機目錄:
terraform.tfvars這個檔案會為環境指定已宣告變數的參數值:
project_id = "PROJECT_ID" builder_service_account = "SERVICE_ACCOUNT_EMAIL" github_repo_name = "projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION/repositories/REPO_NAME" region = "REGION" trigger_name = "TRIGGER_NAME" cloudbuild_yaml_path = "CLOUDBUILD_YAML_PATH" image_builder_config_path = "RECIPE_PATH" gcs_lifecycle_age_days = LIFECYCLE_DAYS ar_repository_id = "REPOSITORY_NAME" ar_package_name = "PACKAGE_NAME"
將下列預留位置替換為現有資源:
PROJECT_ID:現有的Cloud de Confiance by S3NS 專案 ID。SERVICE_ACCOUNT_EMAIL:建構服務帳戶的電子郵件地址,該帳戶是在「設定 Image Builder 服務帳戶」中設定。LOCATION、CONNECTION和REPO_NAME:您在「連結存放區」中設定的 Developer Connect 主機區域、連線名稱和存放區連結。CLOUDBUILD_YAML_PATH:本機目錄中cloudbuild.yaml檔案的相對路徑。您不需要將cloudbuild.yaml簽入 Git 存放區。RECIPE_PATH:imagebuilder.yaml自訂配方檔案的相對路徑,該檔案已簽入 Git 存放區。REPOSITORY_NAME:在「設定 Artifact Registry」中建立的現有一般 Artifact Registry 存放區。
將下列預留位置替換為 Terraform 建立的資源:
REGION:Terraform 佈建 Cloud Storage 暫存 bucket 和 Cloud Build 自動建構觸發條件的目標 Cloud de Confiance區域,例如us-central1。TRIGGER_NAME:Terraform 建立的新 Cloud Build 存放區觸發條件名稱,例如git-push-os-builder。LIFECYCLE_DAYS:Terraform 建立的 Cloud Storage 暫存 bucket 中,中繼構件自動刪除前的保留天數,例如30。PACKAGE_NAME:Terraform 在 Artifact Registry 存放區中建立套件時,應使用的名稱。這個套件會儲存已發布的 OS 映像檔版本,例如ubuntu-custom。
main.tf# Main resource configurations for Image Builder. # 1. Enable Required APIs resource "google_project_service" "apis" { for_each = toset([ "compute.googleapis.com", "cloudbuild.googleapis.com", "artifactregistry.googleapis.com", "serviceusage.googleapis.com", "cloudresourcemanager.googleapis.com", "iam.googleapis.com", "storage.googleapis.com" ]) project = var.project_id service = each.key disable_on_destroy = false } # 2. Project data source to retrieve Project Number data "google_project" "project" { project_id = var.project_id depends_on = [google_project_service.apis] } locals { builder_sa = var.builder_service_account } # 3. Storage Bucket for Image Builder Workdir resource "google_storage_bucket" "workdir_bucket" { name = var.gcs_bucket_name != "" ? var.gcs_bucket_name : "${var.project_id}-vm-builder-workdir" project = var.project_id location = var.region force_destroy = true uniform_bucket_level_access = true lifecycle_rule { action { type = "Delete" } condition { age = var.gcs_lifecycle_age_days } } depends_on = [google_project_service.apis] } # 4. Cloud Build Trigger resource "google_cloudbuild_trigger" "image_builder_trigger" { name = var.trigger_name location = var.region project = var.project_id description = "Trigger that runs Image Builder customization" service_account = var.builder_service_account != "" ? "projects/${var.project_id}/serviceAccounts/${var.builder_service_account}" : null repository_event_config { repository = replace(var.github_repo_name, "gitRepositoryLinks", "repositories") push { branch = "^main$" } } filename = var.cloudbuild_yaml_path substitutions = { _GCS_WORKDIR = "gs://${google_storage_bucket.workdir_bucket.name}/workdir/" _SERVICE_ACCOUNT = "projects/${var.project_id}/serviceAccounts/${local.builder_sa}" _IMAGE_OUTPUT_PATH = "image-builder/binaryOut" _PROJECT_ID = var.project_id _LOCATION = var.region _REPOSITORY_NAME = var.ar_repository_id _PACKAGE_NAME = var.ar_package_name _IMAGE_BUILDER_CONFIG_PATH = var.image_builder_config_path _ARTIFACT_REGISTRY_RESOURCE_URI = "projects/${var.project_id}/locations/${var.region}/repositories/${var.ar_repository_id}/packages/${var.ar_package_name}/versions/v$${BUILD_ID}" } depends_on = [ google_project_service.apis ] }outputs.tf這個檔案定義了部署後傳回終端機的輸出屬性:
output "builder_service_account" { value = local.builder_sa description = "The email representation of the resolved Image Builder service account." } output "workdir_bucket" { value = google_storage_bucket.workdir_bucket.name description = "The name of the storage workdir bucket." } output "artifact_registry_repository" { value = "projects/${var.project_id}/locations/${var.region}/repositories/${var.ar_repository_id}" description = "The fully qualified resource path of the Artifact Registry repository." } output "cloud_build_trigger_id" { value = google_cloudbuild_trigger.image_builder_trigger.trigger_id description = "The unique ID for the created Cloud Build Trigger." }providers.tf這個檔案會設定必要的 Terraform 版本和區域設定:
terraform { required_version = ">= 1.3" required_providers { google = { source = "hashicorp/google" version = ">= 5.0, < 7.0" } } } provider "google" { project = var.project_id region = var.region }variables.tf這個檔案會宣告所有必要和選用的輸入變數和驗證規則:
variable "project_id" { type = string description = "The target Project ID where resources will be created." validation { condition = can(regex("^[a-z0-9-]{6,30}$", var.project_id)) error_message = "The project_id must consist of lowercase letters, numbers, and hyphens, and be between 6 and 30 characters." } } variable "region" { type = string default = "us-central1" description = "Location used for cloud build triggers, storage buckets, and artifact registry." } variable "github_repo_name" { type = string default = "" description = "Developer Connect github repository details, format: projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION/repositories/REPO_LINK" validation { condition = can(regex("^projects/[^/]+/locations/[^/]+/connections/[^/]+/(gitRepositoryLinks|repositories)/[^/]+$", var.github_repo_name)) error_message = "The github_repo_name must follow either the Cloud Build v2 repository link format (using '/repositories/') or the Developer Connect resource format (using '/gitRepositoryLinks/')." } } variable "builder_service_account" { type = string default = "" description = "The email representation of the pre-existing Image Builder service account. If omitted, the default Cloud Build service account will be used." } variable "gcs_bucket_name" { type = string default = "" description = "Custom name for the workdir storage bucket. If left empty, a default name using the project ID will be constructed." } variable "gcs_lifecycle_age_days" { type = number default = 30 description = "The number of days after which temporary logs and artifacts in the storage workdir bucket are deleted." } variable "ar_repository_id" { type = string default = "vm-images" description = "The repository ID for the generic Artifact Registry hosting the final OS image tarballs." } variable "ar_package_name" { type = string default = "image-builder" description = "The package name under which the generic OS image artifact will be registered in Artifact Registry." } variable "trigger_name" { type = string default = "custom-os-image-builder" description = "The name of the Cloud Build trigger." } variable "cloudbuild_yaml_path" { type = string default = "cloudbuild.yaml" description = "The path to the cloudbuild.yaml configuration file relative to the repository root." } variable "image_builder_config_path" { type = string default = "imagebuilder.yaml" description = "The path to the imagebuilder.yaml configuration file relative to the repository root." }如要部署設定,請在包含 Terraform 檔案的目錄中執行下列指令:
- 初始化目錄:
terraform init
- 驗證語法:
terraform validate
- 預覽部署作業:
terraform plan
- 套用設定:
terraform apply
- 初始化目錄:
Go
執行這個範例前,請先將 imagebuilder.yaml 設定檔上傳至 Cloud Storage 暫存 bucket,例如 gs://STAGING_BUCKET_NAME/imagebuilder.yaml。
如要使用 Cloud Build Go 用戶端程式庫,提交執行 Image Builder 管道的 Cloud Build 建構作業,請使用下列範例:
驗證及監控建構作業
如要追蹤建構管道的進度,請完成下列步驟:
前往 Cloud de Confiance 控制台的「Cloud Build」頁面。
在導覽選單中,按一下「History」(記錄),查看執行中或已完成的工作。
在「Builds」(建構作業) 清單中,按一下建構作業的「Build ID」(建構 ID),檢查容器執行記錄。記錄會顯示在 worker VM 中執行的步驟,例如系統套件更新或自訂殼層指令,接著是測試 VM 的驗證測試結果,以及最終輸出註冊。
後續步驟
- 如要透過指令列設定及啟動週期性或自動建構作業,請按照下列步驟操作:
- 驗證圖片來源