GoogleCloudPlatform / GoogleCloudPlatform/agent-starter-pack
`class_methods` spec not populated when deploying to Agent Engine via Terraform (only works with ADK CLI)
- Dominant language
- Python
- Stars
- 6.6k
- Forks
- 1.5k
- PR merge metrics
- No merged PRs in 30d
Description
## 🐛 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:
```hcl
resource "google_vertex_ai_reasoning_engine" "app" {
...
spec {
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`**
```python
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:
```hcl
# 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:
```hcl
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
Contributor guide
Research direction
Start with scripts/generate_class_methods.py and the Terraform examples in data.tf and service.tf, then compare the ADK CLI's use of vertexai._genai._agent_engines_utils. Clarify whether the accepted outcome is documentation, a template utility, or a stable public API; done means Terraform deployments receive the required class_methods specification without relying on undocumented internals.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- google-cloud, python, terraform
- Domain
- ai, cloud, devops
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100