Terraform を使用してエージェントをプロビジョニングする

Terraform を使用すると、Agent Runtime インスタンスを宣言的にプロビジョニングして管理できます。Terraform を使用してエージェントをデプロイする場合は、公式の Google Cloud Terraform プロバイダ(GA プロバイダ または ベータ版プロバイダ)を使用して google_vertex_ai_reasoning_engine リソース を管理します。

このページの手順は、Agent Runtime を使用してコンテナ化されたエージェントをデプロイするの Codelab で説明されている、コンテナ化されたエージェントの実装例に対応しています。

前提条件

Terraform を使用してエージェントをデプロイする前に、次の設定が完了していることを確認してください。

  1. Terraform をインストール(バージョン 1.5.0 以降)し、google_vertex_ai_reasoning_engine リソース(GA プロバイダベータ版プロバイダ)の公式 HashiCorp Terraform Registry ドキュメントを確認します。
  2. 環境を設定し、 Google Cloud 環境と Vertex AI API(aiplatform.googleapis.com)、Artifact Registry API(artifactregistry.googleapis.com)、Cloud Build API(cloudbuild.googleapis.com)を有効にします。
  3. 認証情報を使用してローカル環境を認証します。 Google Cloud

    gcloud auth application-default login
  4. アプリケーション コードをインフラストラクチャ管理から分離するため、エージェント ワークスペースを専用のアプリケーション ディレクトリと Terraform ディレクトリに整理します。

    weather-agent-byoc/
    ├── main.py                # Python ADK agent entrypoint
    ├── requirements.txt       # Python dependencies
    ├── Dockerfile             # Container build definition
    └── terraform/             # Terraform configuration directory
        ├── main.tf            # Agent Runtime resources and specifications
        ├── variables.tf       # Project, region, and container variables
        └── outputs.tf         # Resource name outputs
    
    • アプリケーション ファイルmain.pyrequirements.txtDockerfile): エージェント ロジック、ウェブ フレームワーク ラッパー(FastAPI や ADK App など)、Python の依存関係、コンテナ ビルドの手順が含まれます。

    • Terraform ディレクトリterraform/): リソースのプロビジョニングに使用されるすべての Terraform 構成ファイルが含まれます。

      • variables.tf: project_idlocationrepository_nameimage_tag などの入力変数を宣言します。
      • main.tf: プロバイダの設定、ローカル変数、IAM ロール バインディング、google_vertex_ai_reasoning_engine リソースの仕様を宣言します。
      • outputs.tf: デプロイ後に、プロビジョニングされたリソース属性(Agent Runtime ID や完全なリソース名など)をエクスポートします。
  5. デプロイを実行するユーザーに応じて、適切な IAM ロールを付与します。

    • terraform apply コマンドとローカルビルド コマンドを実行する人間のデベロッパーまたは CI/CD サービス アカウント。

    • システム管理の Agent Runtime サービス エージェント(service-<var>PROJECT_NUMBER</var>@gcp-sa-aiplatform-re.iam.gserviceaccount.com)。

デプロイの準備

Terraform は、Agent Runtime の次のデプロイ パスをサポートしています。

  • ビルド済みのコンテナ イメージからデプロイする: コンテナ イメージをビルドして Artifact Registry({region}-docker.pkg.dev/...)に push し、container_spec を使用してデプロイします。コンテナ ビルドプロセス、カスタム ベースイメージ、デプロイ レイテンシを完全に制御する必要がある場合は、この方法を使用します。
  • ソースファイルまたは Dockerfile からデプロイする: ローカルのソースファイルまたは Dockerfile からエージェントを直接デプロイします。Agent Runtime は、手動でイメージを管理しなくても、コンテナ イメージを自動的にビルドしてプロビジョニングします。
  • Python パッケージ仕様を使用してデプロイする Cloud Storage にステージングされた(package_spec)を使用してデプロイします。Agent Runtime は、手動でイメージを管理しなくても、コンテナ イメージを自動的にビルドしてプロビジョニングします。

ビルド済みのコンテナ イメージからデプロイする

コンテナ イメージをビルドして Artifact Registry に push する場合(カスタム システム ライブラリを含める、コールド スタートのパフォーマンスを最適化する、組織のイメージ ビルドの制御を適用するなど)、container_spec を使用してデプロイできます。イメージ要件の詳細については、コンテナ イメージからデプロイするをご覧ください。

コンテナ イメージは Artifact Registry({LOCATION}-docker.pkg.dev/{PROJECT_ID}/{REPOSITORY}/{IMAGE}:{TAG})に保存し、ポート 8080(または container_spec で指定されたカスタムポート)でリッスンし、ランタイム コントラクトに準拠する必要があります。

  1. ローカルでコンテナ イメージをビルドし、Artifact Registry リポジトリに push します。

    # 1. Authenticate Docker with your Artifact Registry region
    gcloud auth configure-docker us-central1-docker.pkg.dev
    # 2. Build the container image from your application root directory
    cd weather-agent-byoc
    docker build -t us-central1-docker.pkg.dev/PROJECT_ID/agents-repo/weather-agent-image:latest .
    # 3. Push the container image to Artifact Registry
    docker push us-central1-docker.pkg.dev/PROJECT_ID/agents-repo/weather-agent-image:latest
  2. Terraform デプロイ用にビルド済みのコンテナ イメージを構成します。次の構成は、terraform/ ディレクトリに variables.tfmain.tfoutputs.tf ファイルを作成して、Artifact Registry でホストされているビルド済みのコンテナ イメージをデプロイする方法を示しています。

    入力変数(terraform/variables.tf

    variable "project_id" {
      type        = string
      description = "The Google Cloud Project ID"
    }
    
    variable "project_number" {
      type        = string
      description = "The Google Cloud Project Number"
    }
    
    variable "location" {
      type        = string
      default     = "us-central1"
      description = "The region to deploy Agent Runtime"
    }
    
    variable "repository_name" {
      type        = string
      default     = "agents-repo"
      description = "The Artifact Registry repository name"
    }
    
    variable "image_tag" {
      type        = string
      default     = "latest"
      description = "The tag of the container image to deploy"
    }
    

    リソースの仕様(terraform/main.tf

    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = ">= 5.28.0"
        }
      }
    }
    
    provider "google" {
      project = var.project_id
      region  = var.location
    }
    
    locals {
      class_methods = [
        { "name" = "get_session", "api_mode" = "" },
        { "name" = "list_sessions", "api_mode" = "" },
        { "name" = "create_session", "api_mode" = "" },
        { "name" = "delete_session", "api_mode" = "" },
        { "name" = "async_get_session", "api_mode" = "async" },
        { "name" = "async_list_sessions", "api_mode" = "async" },
        { "name" = "async_create_session", "api_mode" = "async" },
        { "name" = "async_delete_session", "api_mode" = "async" },
        { "name" = "async_add_session_to_memory", "api_mode" = "async" },
        { "name" = "async_search_memory", "api_mode" = "async" },
        { "name" = "stream_query", "api_mode" = "stream" },
        { "name" = "async_stream_query", "api_mode" = "async_stream" },
        { "name" = "streaming_agent_run_with_events", "api_mode" = "async_stream" }
      ]
    }
    
    # Grant Artifact Registry Reader permission to the Agent Runtime Service Agent
    resource "google_project_iam_member" "re_service_agent_ar_reader" {
      project = var.project_id
      role    = "roles/artifactregistry.reader"
      member  = "serviceAccount:service-${var.project_number}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"
    }
    
    # Define the Agent Runtime resource with BYOC container configuration
    resource "google_vertex_ai_reasoning_engine" "byoc_weather_agent" {
      display_name = "byoc_weather_agent_tf"
      description  = "BYOC weather agent deployed using Terraform"
      project      = var.project_id
      location     = var.location
    
      spec {
        agent_framework = "google-adk"
    
        container_spec {
          image_uri = "${var.location}-docker.pkg.dev/${var.project_id}/${var.repository_name}/weather-agent-image:${var.image_tag}"
        }
    
        class_methods = jsonencode(local.class_methods)
      }
    
      # Ensure service agent permission exists before provisioning to prevent IMAGE_PULL_BACKOFF
      depends_on = [google_project_iam_member.re_service_agent_ar_reader]
    }
    

    リソース出力(terraform/outputs.tf

    output "reasoning_engine_id" {
      value       = google_vertex_ai_reasoning_engine.byoc_weather_agent.id
      description = "The ID of the deployed Agent Runtime instance"
    }
    
    output "reasoning_engine_resource_name" {
      value       = google_vertex_ai_reasoning_engine.byoc_weather_agent.name
      description = "The resource name of the deployed Agent Runtime instance"
    }
    

Dockerfile またはソース リポジトリからデプロイする

Dockerfile からデプロイする場合は、source_code_spec でソース アーカイブを指定し、空の image_spec {} ブロックを設定して、Dockerfile を使用してコンテナ イメージをビルドするように Agent Runtime に指示します。Dockerfile からビルドされた コンテナは、ランタイム コントラクトに準拠している必要があります。

デプロイの仕組みの詳細については、Dockerfile からデプロイするまたはソースファイルからデプロイするをご覧ください。

  1. アプリケーション コード(main.py)、Python 依存関係マニフェスト(requirements.txt)、コンテナ ビルドの手順(Dockerfile)を圧縮して、gzip 圧縮された tar ファイル アーカイブにします。

  2. アプリケーションのルート ディレクトリから次のコマンドを実行します(この例では、ルート ディレクトリ weather-agent-byoc/ と tar ファイル アーカイブ weather_agent_source.tar.gz を使用しています)。

    cd weather-agent-byoc
    tar -czvf terraform/weather_agent_source.tar.gz main.py requirements.txt Dockerfile
  3. terraform/ ディレクトリに variables.tfmain.tfoutputs.tf ファイルを作成します。

    入力変数(terraform/variables.tf
    variable "project_id" {
      type        = string
      description = "The Google Cloud Project ID"
    }
    
    variable "location" {
      type        = string
      default     = "us-central1"
      description = "The region to deploy Agent Runtime"
    }
    

    リソースの仕様(terraform/main.tf

    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = ">= 5.28.0"
        }
      }
    }
    
    provider "google" {
      project = var.project_id
      region  = var.location
    }
    
    resource "google_vertex_ai_reasoning_engine" "dockerfile_agent" {
      display_name = "dockerfile_weather_agent_tf"
      description  = "BYOC weather agent deployed using Dockerfile"
      project      = var.project_id
      location     = var.location
    
      spec {
        agent_framework = "google-adk"
    
        source_code_spec {
          inline_source {
            source_archive = filebase64("weather_agent_source.tar.gz")
          }
    
          # Empty image_spec instructs the runtime to build using the Dockerfile
          image_spec {}
        }
    
        class_methods = jsonencode([
          { "name" = "get_session", "api_mode" = "" },
          { "name" = "list_sessions", "api_mode" = "" },
          { "name" = "create_session", "api_mode" = "" },
          { "name" = "delete_session", "api_mode" = "" },
          { "name" = "async_get_session", "api_mode" = "async" },
          { "name" = "async_list_sessions", "api_mode" = "async" },
          { "name" = "async_create_session", "api_mode" = "async" },
          { "name" = "async_delete_session", "api_mode" = "async" },
          { "name" = "async_add_session_to_memory", "api_mode" = "async" },
          { "name" = "async_search_memory", "api_mode" = "async" },
          { "name" = "stream_query", "api_mode" = "stream" },
          { "name" = "async_stream_query", "api_mode" = "async_stream" },
          { "name" = "streaming_agent_run_with_events", "api_mode" = "async_stream" }
        ])
      }
    }
    

    リソース出力(terraform/outputs.tf

    output "dockerfile_agent_id" {
      value       = google_vertex_ai_reasoning_engine.dockerfile_agent.id
      description = "Resource ID of the deployed Dockerfile agent"
    }
    

Python パッケージ仕様を使用してデプロイする

エージェントが Python SDK オブジェクトまたはピクル化されたアプリケーション(ADK、LangChain、カスタム Python エージェントなど)を使用してビルドされている場合は、シリアル化されたエージェント(.pkl)と依存関係構成(requirements.txt)を Cloud Storage バケットにステージングし、package_spec を使用して参照できます。

デプロイの仕組みの詳細については、Python オブジェクトからデプロイするをご覧ください。

  1. 次の Python スクリプトを実行してエージェントをシリアル化し、デプロイ アーティファクトを Cloud Storage にステージングします。

    import cloudpickle
    from google.adk.agents import Agent
    from google.cloud import storage
    from vertexai.agent_engines import AdkApp
    PROJECT_ID = "PROJECT_ID"
    BUCKET_NAME = "BUCKET_NAME"
    GCS_DIR = "agents/weather_agent"
    
    # 1. Define agent logic
    root_agent = Agent(
        model="gemini-3.1-flash-lite",
        name="weather_agent",
        description="Agent deployed using Terraform package_spec.",
    )
    local_app = AdkApp(agent=root_agent)
    
    # 2. Upload pickle to Cloud Storage
    storage_client = storage.Client(project=PROJECT_ID)
    bucket = storage_client.bucket(BUCKET_NAME)
    
    pkl_blob = bucket.blob(f"{GCS_DIR}/agent.pkl")
    with pkl_blob.open("wb") as f:
        cloudpickle.dump(local_app, f)
    
    # 3. Upload requirements.txt
    requirements_content = """google-cloud-aiplatform[agent_engines,adk]>=1.144
    cloudpickle==3.0.0
    """
    req_blob = bucket.blob(f"{GCS_DIR}/requirements.txt")
    req_blob.upload_from_string(requirements_content)
    
    print(f"Artifacts uploaded to gs://{BUCKET_NAME}/{GCS_DIR}/")
    
  2. ステージングされた Cloud Storage URI を参照する variables.tfmain.tfoutputs.tf ファイルを terraform/ ディレクトリに作成します。

    入力変数(terraform/variables.tf
    variable "project_id" {
      type        = string
      description = "The Google Cloud Project ID"
    }
    
    variable "location" {
      type        = string
      default     = "us-central1"
      description = "The region to deploy Agent Runtime"
    }
    
    variable "bucket_name" {
      type        = string
      description = "Cloud Storage bucket name containing agent artifacts"
    }
    
    リソースの仕様(terraform/main.tf
    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = ">= 5.28.0"
        }
      }
    }
    
    provider "google" {
      project = var.project_id
      region  = var.location
    }
    
    resource "google_vertex_ai_reasoning_engine" "package_agent" {
      display_name = "weather_agent_package_tf"
      description  = "Agent Runtime instance deployed using package_spec"
      project      = var.project_id
      location     = var.location
    
      spec {
        agent_framework = "google-adk"
        package_spec {
          python_version        = "3.11"
          pickle_object_gcs_uri = "gs://${var.bucket_name}/agents/weather_agent/agent.pkl"
          requirements_gcs_uri  = "gs://${var.bucket_name}/agents/weather_agent/requirements.txt"
        }
      }
    }
    
    リソース出力(terraform/outputs.tf
    output "package_agent_id" {
      value       = google_vertex_ai_reasoning_engine.package_agent.id
      description = "Resource ID of the deployed package agent"
    }
    

環境変数とシークレットを構成する

デプロイする前に、カスタム ランタイム サービス アカウントをエージェントに接続し 環境変数(env)または Secret Manager 参照 (secret_env)を渡すことができます。

次の例では、環境変数(LOCATIONMODELMODEL_REGION)を構成し、Secret Manager から ランタイム サービス アカウントに API キーを terraform/main.tf ファイルを介して安全に渡します。

# 1. Dedicated Runtime Service Account
resource "google_service_account" "agent_runtime_sa" {
  account_id   = "agent-runtime-sa"
  display_name = "Agent Runtime Identity"
  project      = var.project_id
}

# 2. Secret Manager Secret for Agent Credentials
resource "google_secret_manager_secret" "api_key_secret" {
  secret_id = "agent-api-key"
  project   = var.project_id

  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "api_key_version" {
  secret      = google_secret_manager_secret.api_key_secret.id
  secret_data = var.api_key_value
}

# Grant Secret Accessor role to Runtime Service Account
resource "google_secret_manager_secret_iam_member" "secret_accessor" {
  secret_id = google_secret_manager_secret.api_key_secret.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.agent_runtime_sa.email}"
}

# Grant Artifact Registry Reader permission to the Agent Runtime Service Agent
resource "google_project_iam_member" "re_service_agent_ar_reader" {
  project = var.project_id
  role    = "roles/artifactregistry.reader"
  member  = "serviceAccount:service-${var.project_number}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"
}

# 3. Agent Runtime Resource with Environment Variables and Secret References
resource "google_vertex_ai_reasoning_engine" "advanced_weather_agent" {
  display_name = "byoc_weather_agent_advanced_tf"
  description  = "BYOC weather agent with custom service account and secrets"
  project      = var.project_id
  location     = var.location

  spec {
    agent_framework = "google-adk"
    service_account = google_service_account.agent_runtime_sa.email

    container_spec {
      image_uri = "${var.location}-docker.pkg.dev/${var.project_id}/${var.repository_name}/weather-agent-image:${var.image_tag}"
    }

    deployment_spec {
      env {
        name  = "LOCATION"
        value = var.location
      }
      env {
        name  = "MODEL"
        value = "gemini-3.1-flash-lite"
      }
      env {
        name  = "MODEL_REGION"
        value = "global"
      }

      secret_env {
        name = "API_KEY"
        secret_ref {
          secret  = google_secret_manager_secret.api_key_secret.secret_id
          version = "latest"
        }
      }
    }

    class_methods = jsonencode([
      { "name" = "get_session", "api_mode" = "" },
      { "name" = "create_session", "api_mode" = "" },
      { "name" = "stream_query", "api_mode" = "stream" },
      { "name" = "async_stream_query", "api_mode" = "async_stream" }
    ])
  }

  depends_on = [
    google_secret_manager_secret_iam_member.secret_accessor,
    google_project_iam_member.re_service_agent_ar_reader
  ]
}

実行とライフサイクル

標準の Terraform ライフサイクルを実行して、エージェント リソースを計画、デプロイ、呼び出し、破棄します。

Terraform 構成を適用する

Terraform 構成を適用してエージェントをデプロイします。

  1. Terraform ディレクトリに移動します(例: cd weather-agent-byoc/terraform)。

    cd weather-agent-byoc/terraform
  2. 作業ディレクトリを初期化します。

    terraform init
  3. デプロイ プランをプレビューします。

    terraform plan -var="project_id=PROJECT_ID" -var="project_number=PROJECT_NUMBER"
  4. 構成を適用してエージェントをプロビジョニングします。

    terraform apply -var="project_id=PROJECT_ID" -var="project_number=PROJECT_NUMBER"

デプロイしたエージェントに対してクエリを実行する

Terraform が google_vertex_ai_reasoning_engine リソースをプロビジョニングしたら、HTTP POST リクエストを :streamQuery?alt=sse エンドポイントに送信して、サーバー送信イベント(SSE)を使用してレスポンス イベントをリアルタイムでストリーミングします。

LOCATION="LOCATION"
PROJECT_ID="PROJECT_ID"
REASONING_ENGINE_ID="REASONING_ENGINE_ID"
curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{
    "class_method": "async_stream_query",
    "input": {
      "user_id": "terraform_test_user",
      "message": "What is the temperature in Seattle?"
    }
  }' \
  "https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/reasoningEngines/${REASONING_ENGINE_ID}:streamQuery?alt=sse"
  • OAuth アクセス トークン: Authorization: Bearer $(gcloud auth print-access-token) は、ローカル認証情報を使用して有効期間の短い OAuth 2.0 アクセス トークンを生成します。 Google Cloud
  • JSON input エンベロープ: リクエスト本文には、input オブジェクトを含む JSON ペイロードが必要です。明示的なクラスメソッド(async_stream_query など)を呼び出す場合は、"input" とともに "class_method" パラメータを含めます。
  • レスポンス ペイロード: レスポンスは、data: { ... } サーバー送信イベント(SSE)チャンクとして継続的に配信されます。

エージェント リソースを破棄する

リソースをクリーンアップして予期しない課金を防ぐには、terraform/ ディレクトリに移動し(例: cd weather-agent-byoc/terraform)、terraform destroy を実行します。

cd weather-agent-byoc/terraform
terraform destroy -var="project_id=PROJECT_ID" -var="project_number=PROJECT_NUMBER"

次のステップ