Google Cloud CLI または Terraform を使用して、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 をインストールします。 インストール後、 初期化するには、次のコマンドを実行して Google Cloud CLI を初期化します。
gcloud init外部 ID プロバイダ(IdP)を使用している場合は、まず フェデレーション ID を使用して gcloud CLI にログインする必要があります。
-
- デフォルトのリージョンとゾーンを設定します。
-
Google Cloud CLI をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず フェデレーション ID を使用して gcloud CLI にログインする必要があります。
-
ローカルシェルを使用している場合は、ユーザー アカウントのローカル認証情報を作成します。
gcloud auth application-default login
Cloud Shell を使用している場合は、この操作を行う必要はありません。
認証エラーが返され、外部 ID プロバイダ (IdP)を使用している場合は、 連携 ID を使用して gcloud CLI にログインしていることを確認します。
Terraform
ローカル開発環境でこのページの Terraform サンプルを使用するには、gcloud CLI をインストールして初期化し、ユーザー認証情報を使用してアプリケーションのデフォルト認証情報を設定します。
詳細については、 ローカル開発環境の認証を設定するをご覧ください。
必要なロール
Google Cloud CLI または Terraform を使用してイメージ カスタマイズ パイプラインを作成して送信するために必要な権限を取得するには、 プロジェクトに対する 次の IAM ロールの付与を管理者に依頼してください。
- Cloud Build 編集者 (
roles/cloudbuild.builds.editor) - サービス アカウント ユーザー (
roles/iam.serviceAccountUser)
ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。
必要な権限は、カスタム ロールや他の事前定義 ロールから取得することもできます。
構成ファイルを作成する
gcloud CLI または Terraform を使用してパイプラインを構成するには、次の 2 つの構成ファイルを作成します。
imagebuilder.yaml: ベース OS イメージ、ワーカー VM インフラストラクチャの設定、ターゲット イメージの出力の詳細、シェル スクリプトの実行、ファイルの転送、再起動などの順次カスタマイズ手順など、イメージのカスタマイズ レシピを定義します。cloudbuild.yaml: カスタム OS イメージの解析、検証、ビルド、テスト、公開など、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 を使用してパイプラインをデプロイします。次のいずれかのタブを選択します。
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: 実際の Google Cloud プロジェクトでリソースをプロビジョニングします。 必要な API の有効化、Cloud Storage ステージング バケット(workdir_bucket)の作成、Cloud Build トリガー (image_builder_trigger)のデプロイなどを行います。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 ステージング Google Cloud バケットと Cloud Build ビルドトリガーをプロビジョニングするターゲット リージョン(us-central1など)。TRIGGER_NAME: Terraform によって作成された新しい Cloud Build リポジトリ トリガーの名前(git-push-os-builderなど)。LIFECYCLE_DAYS: Terraform によって作成された Cloud Storage ステージング バケット内の中間アーティファクトが自動的に削除されるまでの保持期間(日数)(30など)。PACKAGE_NAME: Artifact Registry リポジトリ内に作成されたパッケージに Terraform が使用する名前。このパッケージには、公開された 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
- ディレクトリを初期化します。
ビルドを検証してモニタリングする
ビルド パイプラインの進行状況を追跡するには、次の手順を完了します。
コンソール Google Cloud で、Cloud Build ページに移動します。
ナビゲーション メニューで [履歴] をクリックして、アクティブなジョブまたは完了したジョブを表示します。
[ビルド] リストで、ビルドの [ビルド ID] をクリックして、コンテナ実行ログを検査します。ログには、ワーカー VM 内で実行されているステップ(システム パッケージの更新やカスタムシェル コマンドなど)が表示され、その後にテスト VM からの検証テストの結果と最終出力の登録が表示されます。
次のステップ
- コマンドラインから定期的なビルドまたは自動ビルドを構成して起動するには:
- イメージの来歴を確認する