使用 Terraform 佈建代理程式

您可以使用 Terraform,以宣告方式佈建及管理 Agent Runtime 執行個體。使用 Terraform 部署代理程式時,您可以使用官方 Google Cloud Terraform 提供者 (GA 版提供者Beta 版提供者) 管理 google_vertex_ai_reasoning_engine 資源

本頁的說明對應於「使用 Agent Runtime 部署容器化代理程式」程式碼研究室中說明的範例容器化代理程式實作。

必要條件

使用 Terraform 部署代理程式前,請確認您已完成下列設定:

  1. 安裝 Terraform (1.5.0 以上版本),並參閱 HashiCorp Terraform Registry 官方說明文件,瞭解 google_vertex_ai_reasoning_engine 資源 (GA 供應程式Beta 版供應程式)。
  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 應用程式)、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/...),然後使用 container_spec 部署。如果您需要完全掌控容器建構程序、自訂基礎映像檔,或降低部署延遲時間,請使用這個方法。
  • 從來源檔案或 Dockerfile 部署:直接從本機來源檔案或 Dockerfile 部署代理程式。Agent Runtime 會自動建構及佈建容器映像檔,不需要手動管理映像檔。
  • 使用 Python 套件規格部署:使用 (package_spec) 在 Cloud Storage 中暫存。Agent Runtime 會自動建構及佈建容器映像檔,不需要手動管理映像檔。

從預先建構的容器映像檔部署

如果您預先建構容器映像檔並推送至 Artifact Registry (例如納入自訂系統程式庫、提升冷啟動效能,或強制執行機構映像檔建構控制項),可以使用 container_spec 部署。如要瞭解映像檔規定,請參閱「從容器映像檔部署」一文。

容器映像檔必須儲存在 Artifact Registry ({LOCATION}-docker.pkg.dev/{PROJECT_ID}/{REPOSITORY}/{IMAGE}:{TAG}) 中,監聽通訊埠 8080 (或 container_spec 中指定的自訂通訊埠),並符合執行階段合約

  1. 在本機建構容器映像檔,並推送至 Artifact Registry 存放區:

    # 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 {} 區塊,指示 Agent Runtime 使用 Dockerfile 建構容器映像檔。從 Dockerfile 建構的容器必須遵守執行階段合約

如要進一步瞭解部署作業的運作方式,請參閱「從 Dockerfile 部署」或「從來源檔案部署」。

  1. 將應用程式程式碼 (main.py)、Python 依附元件資訊清單 (requirements.txt) 和容器建構指令 (Dockerfile) 壓縮為 gzipped 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. terraform/ 目錄中建立 variables.tfmain.tfoutputs.tf 檔案,並參照暫存的 Cloud Storage URI:

    輸入變數 (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),並透過 terraform/main.tf 檔案,將 API 金鑰從 Secret Manager 安全地傳遞至執行階段服務帳戶:

# 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) 會使用本機 Google Cloud 憑證產生短期 OAuth 2.0 存取權杖。
  • JSON input 信封:要求內文必須包含含有 input 物件的 JSON 酬載。呼叫明確類別方法 (例如 async_stream_query) 時,請一併納入 "class_method" 參數和 "input"
  • 回應酬載:回應會以 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"

後續步驟