Skip to content

class_methods spec not populated when deploying to Agent Engine via Terraform (only works with ADK CLI) #888

@benjamin-callonnec

Description

@benjamin-callonnec

🐛 Bug Report / Feature Request

Context

I'm using agent-start-pack to scaffold an agent application and deploying it to Vertex AI Agent Engine via Terraform (instead of the default adk deploy agent-engine CLI flow).


Problem

When deploying through Terraform using the google_vertex_ai_reasoning_engine resource, the class_methods spec inside the spec block is not automatically populated, causing the deployed agent to be missing its registered operations.

This works perfectly fine when deploying via the ADK CLI, which internally handles the class_methods introspection and injection.

The Terraform resource requires the class_methods field to be explicitly provided as a JSON-serialized list of method specs:

resource "google_vertex_ai_reasoning_engine" "app" {
  ...
  spec {
    class_methods = "<json string of class methods>"
    ...
  }
}

But agent-start-pack's generated template does not provide any utility or hook to generate this value outside of the ADK CLI deployment path.


Root Cause

The ADK CLI internally calls utilities from vertexai._genai._agent_engines_utils to:

  1. Introspect register_operations() on the agent instance
  2. Generate the class_methods spec
  3. Inject it into the deployment payload

None of this is exposed or documented for users who deploy via Terraform or other IaC tools.


Workaround I Built

I created a Python script that replicates this introspection and exposes it as a Terraform external data source.

scripts/generate_class_methods.py

import importlib
import json
import logging
import sys
import warnings

logging.basicConfig(stream=sys.stderr, level=logging.WARNING)
warnings.filterwarnings("ignore")

def generate(entrypoint_module: str, entrypoint_object: str) -> list[dict]:
    """Return the class_methods list for the given agent instance."""
    from vertexai._genai import _agent_engines_utils

    module = importlib.import_module(entrypoint_module)
    agent_instance = getattr(module, entrypoint_object)

    registered_operations = _agent_engines_utils._get_registered_operations(agent=agent_instance)
    class_methods_spec = _agent_engines_utils._generate_class_methods_spec_or_raise(
        agent=agent_instance,
        operations=registered_operations,
    )
    return [_agent_engines_utils._to_dict(m) for m in class_methods_spec]

def main() -> None:
    """Main function to generate class_methods spec and print it as JSON."""
    if len(sys.argv) == 3:
        # Standalone usage
        entrypoint_module = sys.argv[1]
        entrypoint_object = sys.argv[2]
    else:
        # Terraform external data source: reads JSON from stdin
        query = json.load(sys.stdin)
        entrypoint_module = query["entrypoint_module"]
        entrypoint_object = query["entrypoint_object"]

    class_methods = generate(entrypoint_module, entrypoint_object)

    # Terraform external data source requires a flat map of strings
    print(json.dumps({"class_methods": json.dumps(class_methods)}))

if __name__ == "__main__":
    main()

data.tf — calls the script via Terraform's external data source:

# Dynamically generate class_methods for each agent by introspecting
# register_operations() from the agent's Python entrypoint module.
# Requires the virtualenv to be active and PYTHONPATH set to the module root.
data "external" "class_methods" {
  for_each = local.agent_names

  program = ["${path.module}/../.venv/bin/python", "${path.module}/scripts/generate_class_methods.py"]

  query = {
    entrypoint_module = "src.${each.value}.agent_engine_app"
    entrypoint_object = "agent_engine"
  }
}

service.tf — consumes the generated spec:

resource "google_vertex_ai_reasoning_engine" "app" {
  ...
  spec {
    class_methods = data.external.class_methods[each.key].result.class_methods
    ...
  }
}

⚠ Note: this script is adapted from the start-pack template but had to be adjusted to match my local project structure (module paths, object names). The core introspection logic is directly borrowed from what the ADK CLI does internally.


Ask / Suggestion

Would it be possible to:

  1. Document the class_methods requirement and how to generate it outside of the ADK CLI, ideally in a dedicated "Deploy via Terraform" guide
  2. Ship a utility script (like the one above) as part of the start-pack template's deployment/ or scripts/ folder so Terraform users don't have to reverse-engineer internal ADK utilities
  3. Or expose a stable public API in the vertexai SDK (instead of relying on _private internal modules) to generate the class_methods spec programmatically

This would greatly improve the experience for teams that manage infrastructure-as-code with Terraform and can't rely on the ADK CLI as part of their CI/CD pipeline.


Environment

  • agent-start-pack version: latest
  • Deployment target: Vertex AI Agent Engine (google_vertex_ai_reasoning_engine)
  • IaC tool: Terraform + google provider
  • Python version: 3.11+
  • google-cloud-aiplatform / vertexai SDK: latest

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions