Aprovisiona agentes con Terraform

Puedes usar Terraform para aprovisionar y administrar instancias de Agent Runtime de forma declarativa. Cuando implementas agentes con Terraform, administras el recurso google_vertex_ai_reasoning_engine con el proveedor oficial de Terraform de Cloud de Confiance by S3NS (proveedor de DG o proveedor de versión beta).

Las instrucciones de esta página corresponden a la implementación de ejemplo del agente alojado en contenedores que se describe en el codelab Implementa un agente alojado en contenedores con Agent Runtime.

Requisitos previos

Antes de usar Terraform para implementar un agente, asegúrate de haber completado la siguiente configuración:

  1. Instala Terraform (versión 1.5.0 o posterior) y revisa la documentación oficial del registro de HashiCorp Terraform para el recurso google_vertex_ai_reasoning_engine (proveedor de GA y proveedor de versión Beta).
  2. Configura tu entorno de Cloud de Confiance by S3NS y habilita la API de Vertex AI (aiplatform.googleapis.com), la API de Artifact Registry (artifactregistry.googleapis.com) y la API de Cloud Build (cloudbuild.googleapis.com).
  3. Autentica tu entorno local con las credenciales de Cloud de Confiance by S3NS :

    gcloud auth application-default login
  4. Para mantener el código de la aplicación separado de la administración de la infraestructura, organiza el espacio de trabajo del agente en directorios dedicados para la aplicación y 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
    
    • Archivos de la aplicación (main.py, requirements.txt, Dockerfile): Contienen la lógica del agente, el wrapper del framework web (como FastAPI o la app de ADK), las dependencias de Python y las instrucciones de compilación del contenedor.

    • Directorio de Terraform (terraform/): Contiene todos los archivos de configuración de Terraform que se usan para aprovisionar recursos:

      • variables.tf: Declara variables de entrada, como project_id, location, repository_name y image_tag.
      • main.tf: Declara la configuración del proveedor, las variables locales, las vinculaciones de roles de IAM y las especificaciones de recursos de google_vertex_ai_reasoning_engine.
      • outputs.tf: Exporta los atributos de recursos aprovisionados, como el ID de Agent Runtime y el nombre completo del recurso, después de la implementación.
  5. Otorga los roles de IAM adecuados según quién ejecute la implementación:

    • Desarrollador humano o cuenta de servicio de CI/CD que ejecuta terraform apply y comandos de compilación locales.

    • Agente de servicio de Agent Runtime administrado por el sistema (service-<var>PROJECT_NUMBER</var>@gcp-sa-aiplatform-re.s3ns-system.iam.gserviceaccount.com).

Prepárate para la implementación

Terraform admite las siguientes rutas de implementación para Agent Runtime:

  • Implementa desde una imagen de contenedor compilada previamente: Compila previamente y envía una imagen de contenedor a Artifact Registry ({region}-docker.pkg.dev/...) y, luego, impleméntala con container_spec. Usa este método cuando necesites un control total sobre el proceso de compilación del contenedor, las imágenes base personalizadas o una menor latencia de implementación.
  • Implementa desde archivos de origen o Dockerfile: Implementa tu agente directamente desde archivos de origen locales o un Dockerfile. Agent Runtime compila y aprovisiona la imagen de contenedor automáticamente sin necesidad de administrarla de forma manual.
  • Implementa con las especificaciones del paquete de Python Implementa con (package_spec) en etapa de pruebas en Cloud Storage. Agent Runtime compila y aprovisiona la imagen de contenedor automáticamente sin necesidad de administrarla de forma manual.

Implementa desde una imagen de contenedor compilada previamente

Si compilas previamente y envías imágenes de contenedor a Artifact Registry (por ejemplo, para incluir bibliotecas de sistema personalizadas, optimizar el rendimiento de inicio en frío o aplicar controles de compilación de imágenes de la organización), puedes implementar con container_spec. Para obtener detalles sobre los requisitos de las imágenes, consulta Implementa desde una imagen de contenedor.

Las imágenes de contenedor deben almacenarse en Artifact Registry ({LOCATION}-docker.pkg.dev/{PROJECT_ID}/{REPOSITORY}/{IMAGE}:{TAG}), escuchar en el puerto 8080 (o un puerto personalizado especificado en container_spec) y cumplir con el contrato de entorno de ejecución.

  1. Compila tu imagen de contenedor de forma local y envíala a tu repositorio de 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. Configura tu imagen de contenedor compilada previamente para la implementación de Terraform. En la siguiente configuración, se muestra cómo implementar una imagen de contenedor compilada previamente alojada en Artifact Registry creando los archivos variables.tf, main.tf y outputs.tf en tu directorio terraform/:

    Variables de entrada (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"
    }
    

    Especificaciones de recursos (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.s3ns-system.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
      region       = 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]
    }
    

    Resultados de recursos (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"
    }
    

Implementa desde un Dockerfile o un repositorio de código fuente

Cuando implementes desde un Dockerfile, especifica tu archivo de origen en source_code_spec y establece un bloque image_spec {} vacío para indicarle a Agent Runtime que compile la imagen de contenedor con tu Dockerfile. El contenedor compilado a partir de tu Dockerfile debe cumplir con el contrato del entorno de ejecución.

Para obtener más detalles sobre cómo funciona la implementación, consulta Implementa desde Dockerfile o Implementa desde archivos fuente.

  1. Comprime el código de tu aplicación (main.py), el manifiesto de dependencia de Python (requirements.txt) y las instrucciones de compilación del contenedor (Dockerfile) en un archivo tar comprimido con gzip.

  2. Ejecuta el siguiente comando desde el directorio raíz de tu aplicación (en el ejemplo, se usa el directorio raíz weather-agent-byoc/ y el archivo tar weather_agent_source.tar.gz):

    cd weather-agent-byoc
    tar -czvf terraform/weather_agent_source.tar.gz main.py requirements.txt Dockerfile
  3. Crea los archivos variables.tf, main.tf y outputs.tf en tu directorio terraform/:

    Variables de entrada (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"
    }
    

    Especificaciones de recursos (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
      region       = 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" }
        ])
      }
    }
    

    Resultados de recursos (terraform/outputs.tf)

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

Implementa con la especificación del paquete de Python

Si tu agente se compila con objetos del SDK de Python o aplicaciones serializadas (como ADK, LangChain o agentes de Python personalizados), puedes almacenar en etapa intermedia tu agente serializado (.pkl) y la configuración de dependencias (requirements.txt) en un bucket de Cloud Storage y hacer referencia a ellos con package_spec.

Para obtener más detalles sobre cómo funciona la implementación, consulta Implementa desde un objeto de Python.

  1. Ejecuta la siguiente secuencia de comandos de Python para serializar tu agente y almacenar en etapa intermedia los artefactos de implementación en 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. Crea los archivos variables.tf, main.tf y outputs.tf en tu directorio terraform/ que hace referencia a los URIs de Cloud Storage en etapa de pruebas:

    Variables de entrada (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"
    }
    
    Especificaciones de recursos (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
      region       = 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"
        }
      }
    }
    
    Resultados de recursos (terraform/outputs.tf)
    output "package_agent_id" {
      value       = google_vertex_ai_reasoning_engine.package_agent.id
      description = "Resource ID of the deployed package agent"
    }
    

Configura variables de entorno y secretos

Antes de la implementación, puedes adjuntar una cuenta de servicio del entorno de ejecución personalizada a tu agente y pasar variables de entorno (env) o referencias de Secret Manager (secret_env).

En el siguiente ejemplo, se configuran las variables de entorno (LOCATION, MODEL, MODEL_REGION) y se pasa una clave de API de forma segura de Secret Manager a la cuenta de servicio del entorno de ejecución a través del archivo 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.s3ns-system.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
  ]
}

Configurar Agent Gateway

Para enrutar el tráfico entre Agent Runtime y las APIs o los clientes externos a través de Agent Gateway, configura el bloque agent_gateway_config dentro de deployment_spec con el proveedor google-beta.

Para ver ejemplos de implementación completos y detalles de los parámetros para el enrutamiento de agente a cualquier lugar (salida) y de cliente a agente (entrada), consulta Enruta el tráfico de entorno de ejecución a través de Agent Gateway.

Administración de puertas de enlace central de varios proyectos

En las arquitecturas empresariales de varios proyectos, puedes administrar un proyecto de administración central que aloje Agent Gateway, Agent Registry y Model Armor, mientras implementas cargas de trabajo de entorno de ejecución en carpetas de proyectos independientes en toda tu organización con Terraform:

  • Agent Gateway central y políticas de autorización: Aprovisiona google_network_services_agent_gateway, google_network_services_authz_extension y google_network_security_authz_policy en el proyecto de administración central. Consulta Configura Agent Gateway.
  • Acceso del agente de servicio entre proyectos: Otorga ar_agw_cross_project_sa (google_project_iam_custom_role) en el proyecto de puerta de enlace central al agente de servicio de entorno de ejecución de cada proyecto de carga de trabajo con google_project_iam_member. Consulta Enruta el tráfico de Agent Runtime a través de Agent Gateway.
  • Políticas de salida y registro central: Registra agentes y herramientas entre proyectos en el registro del proyecto central con google_agent_registry_service y otorga roles/iap.egressor con recursos google_iap_agent_registry_*. Consulta Crea políticas de agentes de IAM.
  • Plantillas y parámetros de configuración mínima de Model Armor: Aplica umbrales de seguridad en toda tu organización o en las carpetas con google_model_armor_floorsetting y google_model_armor_template. Consulta Delega la autorización a Model Armor.

Ejecución y ciclo de vida

Ejecuta el ciclo de vida estándar de Terraform para planificar, implementar, invocar y destruir tus recursos de agentes.

Aplica la configuración de Terraform

Implementa tu agente aplicando la configuración de Terraform:

  1. Cambia al directorio de Terraform (por ejemplo, cd weather-agent-byoc/terraform):

    cd weather-agent-byoc/terraform
  2. Inicializa el directorio de trabajo:

    terraform init
  3. Obtén una vista previa del plan de implementación:

    terraform plan -var="project_id=PROJECT_ID" -var="project_number=PROJECT_NUMBER"
  4. Aplica la configuración para aprovisionar el agente:

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

Hazle preguntas al agente implementado

Después de que Terraform aprovisione el recurso google_vertex_ai_reasoning_engine, envía una solicitud HTTP POST al extremo :streamQuery?alt=sse para transmitir eventos de respuesta en tiempo real con eventos enviados por el servidor (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"
  • Token de acceso de OAuth: Authorization: Bearer $(gcloud auth print-access-token) genera un token de acceso de OAuth 2.0 de corta duración con tus credenciales locales de Cloud de Confiance by S3NS .
  • Envoltorio JSON input: El cuerpo de la solicitud requiere una carga útil de JSON que contenga un objeto input. Cuando llames a métodos de clase explícitos (como async_stream_query), incluye el parámetro "class_method" junto con "input".
  • Carga útil de la respuesta: Las respuestas se entregan de forma continua como fragmentos de eventos enviados por el servidor (SSE) de data: { ... }.

Destruye los recursos del agente

Para limpiar los recursos y evitar cargos de facturación inesperados, cambia al directorio terraform/ (por ejemplo, cd weather-agent-byoc/terraform) y ejecuta terraform destroy:

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

¿Qué sigue?