gcloud CLI、Terraform、または Go などのクライアント ライブラリを使用して、Image Builder パイプラインをプログラムで構成して送信できます。パイプラインをプログラムで構成すると、インフラストラクチャ設定、ベース OS イメージ、カスタマイズ アクション、検証テストを宣言型構成ファイルで定義できます。
始める前に
- 環境を準備するの手順に沿って環境を設定します。
- Terraform を使用してパイプラインをデプロイする場合や、リポジトリからビルドを自動化する場合は、Cloud Build リポジトリ(
2nd gen)または Developer Connect 接続リンクを使用して、GitHub、GitLab、Bitbucket リポジトリを接続します。 - Terraform を使用する場合は、Terraform CLI バージョン 1.3 以降をインストールします。
-
まだ設定していない場合は、認証を設定します。認証では、 Google Cloud サービスと API にアクセスするための ID が確認されます。ローカル開発環境からコードまたはサンプルを実行するには、次のいずれかのオプションを選択して Compute Engine に対する認証を行います。
このページのサンプルをどのように使うかに応じて、タブを選択してください。
gcloud
-
Google Cloud CLI をインストールし、 フェデレーション ID を使用して gcloud CLI にログインします。ログイン後、次のコマンドを実行して Google Cloud CLI を初期化します。
gcloud init
-
- デフォルトのリージョンとゾーンを設定します。
-
Google Cloud CLI をインストールします。
-
フェデレーション ID(連携 ID)を使用するように gcloud CLI を構成します。
詳細については、 フェデレーション ID を使用して gcloud CLI にログインするをご覧ください。
-
ユーザー アカウントのローカル認証情報を作成します。
gcloud auth application-default login
認証エラーが返された場合は、 フェデレーション ID を使用して gcloud CLI にログインしていることを確認します。
-
Google Cloud CLI をインストールします。
-
フェデレーション ID(連携 ID)を使用するように gcloud CLI を構成します。
詳細については、 フェデレーション ID を使用して gcloud CLI にログインするをご覧ください。
-
ユーザー アカウントのローカル認証情報を作成します。
gcloud auth application-default login
認証エラーが返された場合は、 フェデレーション ID を使用して gcloud CLI にログインしていることを確認します。
Terraform
ローカル開発環境でこのページの Terraform サンプルを使用するには、gcloud CLI をインストールして初期化し、ユーザー認証情報を使用してアプリケーションのデフォルト認証情報を設定します。
詳細については、 ローカル開発環境の認証を設定するをご覧ください。
Go
ローカル開発環境でこのページの Go サンプルを使用するには、gcloud CLI をインストールして初期化し、ユーザー認証情報を使用してアプリケーションのデフォルト認証情報を設定します。
詳細については、 ローカル開発環境の認証を設定するをご覧ください。
必要なロール
画像カスタマイズ パイプラインをプログラムで作成して送信するために必要な権限を取得するには、プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。
- Cloud Build 編集者 (
roles/cloudbuild.builds.editor) - サービス アカウント ユーザー(
roles/iam.serviceAccountUser)
ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
構成ファイルを作成する
gcloud CLI または Terraform を使用してパイプラインを構成するには、次の 2 つの構成ファイルを作成します。
imagebuilder.yaml: イメージのカスタマイズ レシピを定義します。これには、ベース OS イメージ、ワーカー VM インフラストラクチャの設定、ターゲット イメージの出力の詳細、シェル スクリプトの実行、ファイルの転送、再起動などの順次カスタマイズ ステップが含まれます。cloudbuild.yaml: Cloud Build でのビルドプロセスのステップ(カスタム OS イメージの解析、検証、ビルド、テスト、公開など)をオーケストレートします。
Go を使用してビルドを送信する場合は、imagebuilder.yaml ファイルを作成して Cloud Storage バケットにアップロードするだけで済みます。これは、Go サンプルがコードで Cloud Build オーケストレーション ステップを定義しているためです。
イメージ構成ファイルを作成する
イメージ構成を指定するには、ローカル ディレクトリに imagebuilder.yaml という名前のファイルを作成します。サポートされているすべてのスキーマ フィールドとカスタマイズ アクションの完全なリストについては、カスタマイズ レシピのスキーマとサポートされているカスタマイズ アクションをご覧ください。
次の imagebuilder.yaml ファイルのサンプルでは、指定したリージョンとゾーンで e2-standard-4 ワーカー 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 が利用可能なリージョンでのみサポートされています。
- ワーカー VM
ZONEは、指定したREGION内に配置する必要があります。 - ネットワーク レイテンシを最小限に抑え、クロスリージョンの下り(外向き)料金を回避するには、ワーカー VM ゾーン、Cloud Storage ステージング バケット、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 バケット。バケットがない場合は、gcloud storage buckets create gs://STAGING_BUCKET_NAMEを実行して作成できます。Terraform を使用してパイプラインをデプロイすると、Terraform によってこのバケットが自動的に作成されます。PROJECT_ID: 実際の Google Cloud プロジェクト ID。REGION: Artifact Registry リポジトリの Google Cloud リージョン(例:us-east1、europe-west1)。SERVICE_ACCOUNT_EMAIL: 必要な IAM 権限で構成したサービス アカウントのメールアドレス。REPOSITORYとPACKAGE: Artifact Registry で作成されたターゲット リポジトリとパッケージ名。Artifact Registry レジストリを設定するには、Artifact Registry を構成するをご覧ください。
ビルド パイプラインを作成して送信する
イメージ カスタマイズ パイプラインを実行するには、gcloud CLI を使用してビルドを送信するか、Terraform を使用してパイプラインをデプロイするか、Go クライアント ライブラリを使用してビルドを送信します。次のいずれかのタブを選択します。
gcloud
イメージ カスタマイズ パイプラインをデプロイして実行するには、両方の構成ファイルを含むローカル ターミナル ディレクトリから 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: 実際の Google Cloud プロジェクト ID。REGION: 画像カスタマイズ パイプライン ジョブを実行する Google Cloud リージョン。SERVICE_ACCOUNT_EMAIL: 必要な IAM 権限で構成されたサービス アカウントのメールアドレス。
このコマンドは、カスタマイズ ワークスペースをアップロードし、Cloud Build の実行を登録して、オーケストレーション コンテナを起動します。
Terraform
カスタマイズされた OS イメージを自動的にビルドして検証するために必要なインフラストラクチャをプロビジョニングするには、Terraform を使用します。この Terraform 構成は、次のタスクを完了します。
- 必要な Google Cloud API を有効にします。
- 一時ログとビルド アーティファクトを保存するための専用の Cloud Storage バケット(
workdir_bucket)を作成します。 - Developer Connect GitHub リポジトリ接続にリンクされた Cloud Build トリガー(
image_builder_trigger)を構成します。
Terraform 構成ファイルを作成する
Terraform を使用してパイプライン インフラストラクチャを整理してデプロイするには、次の手順を完了します。
ローカル ワークステーションまたは CI/CD 環境に、アプリケーション リポジトリとは別に専用のディレクトリを作成し、そのディレクトリに移動します。
mkdir terraform-image-builder && cd terraform-image-builder
このディレクトリに、次の 5 つの Terraform 構成ファイルを作成します。
terraform.tfvars: プロジェクト固有の変数の値を設定します。main.tf: 必要な API の有効化、Cloud Storage ステージング バケット(workdir_bucket)の作成、Cloud Build トリガー(image_builder_trigger)のデプロイなど、 Google Cloud プロジェクトにリソースをプロビジョニングします。outputs.tf: デプロイ後にターミナルに表示される出力値(トリガー ID、ステージング バケット名など)を定義します。providers.tf: 必要な Terraform バージョン(>= 1.3)を指定し、 Google Cloud プロバイダ(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: 既存のGoogle Cloud プロジェクト ID。SERVICE_ACCOUNT_EMAIL: Image Builder サービス アカウントを構成するで構成したビルド サービス アカウントのメールアドレス。LOCATION、CONNECTION、REPO_NAME: リポジトリを接続するで構成された Developer Connect ホスト リージョン、接続名、リポジトリ リンク。CLOUDBUILD_YAML_PATH: ローカル ディレクトリ内のcloudbuild.yamlファイルの相対パス。cloudbuild.yamlを Git リポジトリにチェックインする必要はありません。RECIPE_PATH: Git リポジトリにチェックインされたimagebuilder.yamlカスタマイズ レシピ ファイルの相対パス。REPOSITORY_NAME: Artifact Registry を構成するで作成した既存の汎用 Artifact Registry リポジトリ。
Terraform が作成するリソースの次のプレースホルダを置き換えます。
REGION: Terraform が Cloud Storage ステージング バケットと Cloud Build ビルドトリガーをプロビジョニングするターゲット Google Cloudリージョン(例:us-central1)。TRIGGER_NAME: Terraform によって作成された新しい Cloud Build リポジトリ トリガーの名前(例:git-push-os-builder)。LIFECYCLE_DAYS: Terraform によって作成された Cloud Storage ステージング バケット内の中間アーティファクトが自動的に削除されるまでの保持期間(日数)。例: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 ステージング バケット(gs://STAGING_BUCKET_NAME/imagebuilder.yaml など)にアップロードします。
Cloud Build Go クライアント ライブラリを使用して、Image Builder パイプラインを実行する Cloud Build ビルドを送信するには、次のサンプルを使用します。
ビルドを検証してモニタリングする
ビルド パイプラインの進行状況を追跡するには、次の手順を行います。
Google Cloud コンソールで、[Cloud Build] ページに移動します。
ナビゲーション メニューで [履歴] をクリックして、アクティブなジョブまたは完了したジョブを表示します。
[ビルド] リストで、ビルドのビルド ID をクリックして、コンテナ実行ログを検査します。ログには、システム パッケージの更新やカスタムシェル コマンドなど、ワーカー VM 内で実行されているステップが表示されます。その後に、テスト VM からの検証テストの結果と最終出力の登録が表示されます。
次のステップ
- コマンドラインから定期的なビルドまたは自動ビルドを構成して起動するには:
- イメージの来歴を確認する