Add ability to use existing source files in GCS. (#3653)

This commit is contained in:
Luca Prete
2026-01-15 16:39:05 +00:00
committed by GitHub
parent 620551cbb1
commit ecb92b508c
6 changed files with 155 additions and 18 deletions

View File

@@ -114,6 +114,37 @@ module "agent_engine" {
# tftest inventory=minimal-pickle.yaml
```
You may want to upload your files on the GCS bucket outside Terrafrom.
In this example, the module expects your package config files to be already present in the GCS bucket.
```hcl
module "agent_engine" {
source = "./fabric/modules/agent-engine"
name = "my-agent"
project_id = var.project_id
region = var.region
agent_engine_config = {
agent_framework = "google-adk"
}
bucket_config = {
create = false
}
deployment_files = {
package_config = {
are_paths_local = false
dependencies_path = "dependencies.tar.gz"
pickle_path = "pickle.pkl"
requirements_path = "requirements.txt"
}
source_config = null
}
}
# tftest inventory=pickle-gcs.yaml
```
### Unmanaged deployments
By default, this module tracks and controls code updates. This means you can only the agent code via Terraform.
@@ -269,15 +300,15 @@ The module allows you to dynamically reference context values for resources crea
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [agent_engine_config](variables.tf#L17) | The agent configuration. | <code title="object&#40;&#123;&#10; agent_framework &#61; string&#10; class_methods &#61; optional&#40;list&#40;any&#41;, &#91;&#93;&#41;&#10; container_concurrency &#61; optional&#40;number&#41;&#10; environment_variables &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; max_instances &#61; optional&#40;number&#41;&#10; min_instances &#61; optional&#40;number&#41;&#10; python_version &#61; optional&#40;string, &#34;3.12&#34;&#41;&#10; resource_limits &#61; optional&#40;object&#40;&#123;&#10; cpu &#61; string&#10; memory &#61; string&#10; &#125;&#41;&#41;&#10; secret_environment_variables &#61; optional&#40;map&#40;object&#40;&#123;&#10; secret_id &#61; string&#10; version &#61; optional&#40;string, &#34;latest&#34;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [name](variables.tf#L121) | The name of the agent. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L127) | The id of the project where to deploy the agent. | <code>string</code> | ✓ | |
| [region](variables.tf#L133) | The region where to deploy the agent. | <code>string</code> | ✓ | |
| [name](variables.tf#L122) | The name of the agent. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L128) | The id of the project where to deploy the agent. | <code>string</code> | ✓ | |
| [region](variables.tf#L134) | The region where to deploy the agent. | <code>string</code> | ✓ | |
| [bucket_config](variables.tf#L40) | The GCS bucket configuration. | <code title="object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; deletion_protection &#61; optional&#40;bool, true&#41;&#10; name &#61; optional&#40;string&#41;&#10; uniform_bucket_level_access &#61; optional&#40;bool, true&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [context](variables.tf#L52) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; custom_roles &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; iam_principals &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; kms_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [deployment_files](variables.tf#L65) | The to source files path and names. | <code title="object&#40;&#123;&#10; package_config &#61; optional&#40;object&#40;&#123;&#10; dependencies_path &#61; optional&#40;string, &#34;.&#47;src&#47;dependencies.tar.gz&#34;&#41;&#10; pickle_path &#61; optional&#40;string, &#34;.&#47;src&#47;pickle.pkl&#34;&#41;&#10; requirements_path &#61; optional&#40;string, &#34;.&#47;src&#47;requirements.txt&#34;&#41;&#10; &#125;&#41;, null&#41;&#10; source_config &#61; optional&#40;object&#40;&#123;&#10; entrypoint_module &#61; optional&#40;string, &#34;agent&#34;&#41;&#10; entrypoint_object &#61; optional&#40;string, &#34;agent&#34;&#41;&#10; requirements_path &#61; optional&#40;string, &#34;requirements.txt&#34;&#41;&#10; source_path &#61; optional&#40;string, &#34;.&#47;src&#47;source.tar.gz&#34;&#41;&#10; &#125;&#41;, null&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; package_config &#61; null&#10; source_config &#61; &#123;&#125;&#10;&#125;">&#123;&#8230;&#125;</code> |
| [description](variables.tf#L101) | The Agent Engine description. | <code>string</code> | | <code>&#34;Terraform managed.&#34;</code> |
| [encryption_key](variables.tf#L108) | The full resource name of the Cloud KMS CryptoKey. | <code>string</code> | | <code>null</code> |
| [managed](variables.tf#L114) | Whether the Terraform module should control the code updates. | <code>bool</code> | | <code>true</code> |
| [deployment_files](variables.tf#L65) | The to source files path and names. | <code title="object&#40;&#123;&#10; package_config &#61; optional&#40;object&#40;&#123;&#10; are_paths_local &#61; optional&#40;bool, true&#41;&#10; dependencies_path &#61; optional&#40;string, &#34;.&#47;src&#47;dependencies.tar.gz&#34;&#41;&#10; pickle_path &#61; optional&#40;string, &#34;.&#47;src&#47;pickle.pkl&#34;&#41;&#10; requirements_path &#61; optional&#40;string, &#34;.&#47;src&#47;requirements.txt&#34;&#41;&#10; &#125;&#41;, null&#41;&#10; source_config &#61; optional&#40;object&#40;&#123;&#10; entrypoint_module &#61; optional&#40;string, &#34;agent&#34;&#41;&#10; entrypoint_object &#61; optional&#40;string, &#34;agent&#34;&#41;&#10; requirements_path &#61; optional&#40;string, &#34;requirements.txt&#34;&#41;&#10; source_path &#61; optional&#40;string, &#34;.&#47;src&#47;source.tar.gz&#34;&#41;&#10; &#125;&#41;, null&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; package_config &#61; null&#10; source_config &#61; &#123;&#125;&#10;&#125;">&#123;&#8230;&#125;</code> |
| [description](variables.tf#L102) | The Agent Engine description. | <code>string</code> | | <code>&#34;Terraform managed.&#34;</code> |
| [encryption_key](variables.tf#L109) | The full resource name of the Cloud KMS CryptoKey. | <code>string</code> | | <code>null</code> |
| [managed](variables.tf#L115) | Whether the Terraform module should control the code updates. | <code>bool</code> | | <code>true</code> |
| [service_account_config](variables-serviceaccount.tf#L18) | Service account configurations. | <code title="object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; display_name &#61; optional&#40;string&#41;&#10; email &#61; optional&#40;string&#41;&#10; name &#61; optional&#40;string&#41;&#10; roles &#61; optional&#40;list&#40;string&#41;, &#91;&#10; &#34;roles&#47;aiplatform.user&#34;,&#10; &#34;roles&#47;storage.objectViewer&#34;,&#10; &#34;roles&#47;viewer&#34;&#10; &#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
## Outputs

View File

@@ -88,10 +88,22 @@ resource "google_vertex_ai_reasoning_engine" "managed" {
for_each = var.deployment_files.package_config != null ? { 1 = 1 } : {}
content {
python_version = var.agent_engine_config.python_version
dependency_files_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.dependencies[0].name}"
requirements_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.requirements[0].name}"
pickle_object_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.pickle[0].name}"
python_version = var.agent_engine_config.python_version
dependency_files_gcs_uri = (
var.deployment_files.package_config.are_paths_local
? "gs://${local.bucket_name}/${google_storage_bucket_object.dependencies[0].name}"
: var.deployment_files.package_config.dependencies_path
)
requirements_gcs_uri = (
var.deployment_files.package_config.are_paths_local
? "gs://${local.bucket_name}/${google_storage_bucket_object.requirements[0].name}"
: var.deployment_files.package_config.requirements_path
)
pickle_object_gcs_uri = (
var.deployment_files.package_config.are_paths_local
? "gs://${local.bucket_name}/${google_storage_bucket_object.pickle[0].name}"
: var.deployment_files.package_config.pickle_path
)
}
}

View File

@@ -88,10 +88,22 @@ resource "google_vertex_ai_reasoning_engine" "unmanaged" {
for_each = var.deployment_files.package_config == null ? {} : { 1 = 1 }
content {
python_version = var.agent_engine_config.python_version
dependency_files_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.dependencies[0].name}"
requirements_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.requirements[0].name}"
pickle_object_gcs_uri = "gs://${local.bucket_name}/${google_storage_bucket_object.pickle[0].name}"
python_version = var.agent_engine_config.python_version
dependency_files_gcs_uri = (
var.deployment_files.package_config.are_paths_local
? "gs://${local.bucket_name}/${google_storage_bucket_object.dependencies[0].name}"
: var.deployment_files.package_config.dependencies_path
)
requirements_gcs_uri = (
var.deployment_files.package_config.are_paths_local
? "gs://${local.bucket_name}/${google_storage_bucket_object.requirements[0].name}"
: var.deployment_files.package_config.requirements_path
)
pickle_object_gcs_uri = (
var.deployment_files.package_config.are_paths_local
? "gs://${local.bucket_name}/${google_storage_bucket_object.pickle[0].name}"
: var.deployment_files.package_config.pickle_path
)
}
}

View File

@@ -67,7 +67,10 @@ resource "google_storage_bucket" "default" {
}
resource "google_storage_bucket_object" "dependencies" {
count = var.deployment_files.package_config != null ? 1 : 0
count = (
var.deployment_files.package_config != null
&& var.deployment_files.package_config.are_paths_local ? 1 : 0
)
name = "dependencies.tar.gz"
bucket = local.bucket_name
source = try(var.deployment_files.package_config.dependencies_path, null)
@@ -77,7 +80,10 @@ resource "google_storage_bucket_object" "dependencies" {
}
resource "google_storage_bucket_object" "pickle" {
count = var.deployment_files.package_config != null ? 1 : 0
count = (
var.deployment_files.package_config != null
&& var.deployment_files.package_config.are_paths_local ? 1 : 0
)
name = "pickle.pkl"
bucket = local.bucket_name
source = try(var.deployment_files.package_config.pickle_path, null)
@@ -87,7 +93,10 @@ resource "google_storage_bucket_object" "pickle" {
}
resource "google_storage_bucket_object" "requirements" {
count = var.deployment_files.package_config != null ? 1 : 0
count = (
var.deployment_files.package_config != null
&& var.deployment_files.package_config.are_paths_local ? 1 : 0
)
name = "requirements.txt"
bucket = local.bucket_name
source = try(var.deployment_files.package_config.requirements_path, null)

View File

@@ -66,6 +66,7 @@ variable "deployment_files" {
description = "The to source files path and names."
type = object({
package_config = optional(object({
are_paths_local = optional(bool, true)
dependencies_path = optional(string, "./src/dependencies.tar.gz")
pickle_path = optional(string, "./src/pickle.pkl")
requirements_path = optional(string, "./src/requirements.txt")

View File

@@ -0,0 +1,72 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
values:
module.agent_engine.google_project_iam_member.default["roles/aiplatform.user"]:
condition: []
member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com
project: project-id
role: roles/aiplatform.user
module.agent_engine.google_project_iam_member.default["roles/storage.objectViewer"]:
condition: []
member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com
project: project-id
role: roles/storage.objectViewer
module.agent_engine.google_project_iam_member.default["roles/viewer"]:
condition: []
member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com
project: project-id
role: roles/viewer
module.agent_engine.google_service_account.service_account[0]:
account_id: my-agent
create_ignore_already_exists: null
description: null
disabled: false
display_name: my-agent
email: my-agent@project-id.iam.gserviceaccount.com
member: serviceAccount:my-agent@project-id.iam.gserviceaccount.com
project: project-id
timeouts: null
module.agent_engine.google_vertex_ai_reasoning_engine.managed[0]:
description: Terraform managed.
display_name: my-agent
encryption_spec: []
project: project-id
region: europe-west8
spec:
- agent_framework: google-adk
class_methods: null
deployment_spec: []
package_spec:
- dependency_files_gcs_uri: dependencies.tar.gz
pickle_object_gcs_uri: pickle.pkl
python_version: '3.12'
requirements_gcs_uri: requirements.txt
service_account: my-agent@project-id.iam.gserviceaccount.com
source_code_spec: []
timeouts: null
module.agent_engine.time_sleep.wait_5_minutes:
create_duration: 5m
destroy_duration: null
triggers: null
counts:
google_project_iam_member: 3
google_service_account: 1
google_vertex_ai_reasoning_engine: 1
modules: 1
resources: 6
time_sleep: 1
outputs: {}