diff --git a/README.md b/README.md index 6c2375998..ec08bbbc8 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Currently available modules: - **networking** - [DNS](./modules/dns), [DNS Response Policy](./modules/dns-response-policy/), [Cloud Endpoints](./modules/endpoints), [address reservation](./modules/net-address), [NAT](./modules/net-cloudnat), [VLAN Attachment](./modules/net-vlan-attachment/), [External Application LB](./modules/net-lb-app-ext/), [External Passthrough Network LB](./modules/net-lb-ext), [External Regional Application Load Balancer](./modules/net-lb-app-ext-regional/), [Firewall policy](./modules/net-firewall-policy), [Internal Application LB](./modules/net-lb-app-int), [Cross-region Internal Application LB](./modules/net-lb-app-int-cross-region), [Internal Passthrough Network LB](./modules/net-lb-int), [Internal Proxy Network LB](./modules/net-lb-proxy-int), [IPSec over Interconnect](./modules/net-ipsec-over-interconnect), [VPC](./modules/net-vpc), [VPC factory](./modules/net-vpc-factory/README.md), [VPC firewall](./modules/net-vpc-firewall), [VPC peering](./modules/net-vpc-peering), [VPN dynamic](./modules/net-vpn-dynamic), [HA VPN](./modules/net-vpn-ha), [VPN static](./modules/net-vpn-static), [Service Directory](./modules/service-directory), [Secure Web Proxy](./modules/net-swp) - **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [COS container](./modules/cloud-config-container/cos-generic-metadata/) (coredns, mysql, onprem, squid), [GKE cluster](./modules/gke-cluster-standard), [GKE hub](./modules/gke-hub), [GKE nodepool](./modules/gke-nodepool), [GCVE private cloud](./modules/gcve-private-cloud) - **data** - [AlloyDB instance](./modules/alloydb), [Analytics Hub](./modules/analytics-hub), [BigQuery dataset](./modules/bigquery-dataset), [Biglake Catalog](./modules/biglake-catalog), [Bigtable instance](./modules/bigtable-instance), [Dataplex](./modules/dataplex), [Dataplex Aspect Types](./modules/dataplex-aspect-types/), [Dataplex DataScan](./modules/dataplex-datascan), [Cloud SQL instance](./modules/cloudsql-instance), [Spanner instance](./modules/spanner-instance), [Firestore](./modules/firestore), [Data Catalog Policy Tag](./modules/data-catalog-policy-tag), [Data Catalog Tag](./modules/data-catalog-tag), [Data Catalog Tag Template](./modules/data-catalog-tag-template), [Datafusion](./modules/datafusion), [Dataproc](./modules/dataproc), [GCS](./modules/gcs), [Pub/Sub](./modules/pubsub), [Dataform Repository](./modules/dataform-repository/), [Looker Core](./modules/looker-core) +- **AI** - [Agentspace](./modules/agentspace/README.md) - **development** - [API Gateway](./modules/api-gateway), [Apigee](./modules/apigee), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository), [Secure Source Manager instance](./modules/secure-source-manager-instance), [Workstation cluster](./modules/workstation-cluster) - **security** - [Binauthz](./modules/binauthz/), [Certificate Authority Service (CAS)](./modules/certificate-authority-service), [KMS](./modules/kms), [SecretManager](./modules/secret-manager), [VPC Service Control](./modules/vpc-sc), [Certificate Manager](./modules/certificate-manager/) - **serverless** - [Cloud Function v1](./modules/cloud-function-v1), [Cloud Function v2](./modules/cloud-function-v2), [Cloud Run](./modules/cloud-run), [Cloud Run v2](./modules/cloud-run-v2) diff --git a/modules/README.md b/modules/README.md index 6851500f0..48105f494 100644 --- a/modules/README.md +++ b/modules/README.md @@ -101,6 +101,10 @@ These modules are used in the examples included in this repository. If you are u - [Pub/Sub](./pubsub) - [Spanner instance](./spanner-instance) +## AI + +- [Agentspace](./agentspace/README.md) + ## Development - [API Gateway](./api-gateway) diff --git a/modules/agentspace/README.md b/modules/agentspace/README.md new file mode 100644 index 000000000..033517b6d --- /dev/null +++ b/modules/agentspace/README.md @@ -0,0 +1,253 @@ +# Agentspace + +This module handles the creation of Agentspace data sources, engines and related configurations. + + +* [Agentspace module](#agentspace) + * [APIs](#apis) + * [Quota Project](#quota-project) + * [Examples](#examples) + * [Chat Engine](#chat-engine) + * [Search Engine](#search-engine) + * [Deploy your service into a region](#deploy-your-service-into-a-region) + * [Reference Existing Data Sources](#reference-existing-data-sources) + * [Using multiple data stores](#using-multiple-data-stores) + * [Set data store schemas](#set-data-store-schemas) + * [Back data stores with websites data](#back-data-stores-with-websites-data) + * [Variables](#variables) + * [Outputs](#outputs) + + +## APIs + +This module uses the API `discoveryengine.googleapis.com` + +## Quota Project + +To run this module you'll need to set a quota project. + +```shell +export GOOGLE_BILLING_PROJECT=your-project-id +export USER_PROJECT_OVERRIDE=true +``` + +## Examples + +### Chat Engine + +This is a minimal example to create a Chat Engine agent. + +```hcl +module "agentspace" { + source = "./fabric/modules/agentspace" + name = "my-chat-app" + project_id = var.project_id + data_stores_configs = { + data-store-1 = { + solution_types = ["SOLUTION_TYPE_CHAT"] + } + } + engines_configs = { + my-chat-engine = { + data_store_ids = ["data-store-1"] + chat_engine_config = { + company_name = "Google" + default_language_code = "en" + time_zone = "America/Los_Angeles" + } + } + } +} +# tftest modules=1 resources=2 +``` + +### Search Engine + +This is a minimal example to create a Search Engine agent. + +```hcl +module "agentspace" { + source = "./fabric/modules/agentspace" + name = "my-search-app" + project_id = var.project_id + data_stores_configs = { + data-store-1 = { + solution_types = ["SOLUTION_TYPE_SEARCH"] + } + } + engines_configs = { + my-search-engine = { + data_store_ids = ["data-store-1"] + search_engine_config = {} + } + } +} +# tftest modules=1 resources=2 +``` + +### Deploy your service into a region + +By default services are deployed globally. You optionally specify a region where to deploy them. + +```hcl +module "agentspace" { + source = "./fabric/modules/agentspace" + name = "my-chat-app" + project_id = var.project_id + location = var.region + data_stores_configs = { + data-store-1 = { + solution_types = ["SOLUTION_TYPE_CHAT"] + } + } + engines_configs = { + my-chat-engine = { + data_store_ids = ["data-store-1"] + chat_engine_config = { + company_name = "Google" + default_language_code = "en" + time_zone = "America/Los_Angeles" + } + } + } +} +# tftest modules=1 resources=2 +``` + +### Reference existing data sources + +You can reference from engines existing data sources created outside this module, by passing their ids. In this case, you'll need to configure in the engine valid `industry_vertical` and `location`. + +```hcl +module "agentspace" { + source = "./fabric/modules/agentspace" + name = "my-search-app" + project_id = var.project_id + engines_configs = { + my-search-engine = { + data_store_ids = [ + "projects/my-project/locations/global/collections/my-collection/dataStores/data-store-1" + ] + industry_vertical = "GENERIC" + search_engine_config = {} + } + } +} +# tftest modules=1 resources=1 +``` + +### Using multiple data stores + +You can create and connect from your engines multiple data stores. + +```hcl +module "agentspace" { + source = "./fabric/modules/agentspace" + name = "my-chat-app" + project_id = var.project_id + data_stores_configs = { + data-store-1 = { + solution_types = ["SOLUTION_TYPE_CHAT"] + } + data-store-2 = { + solution_types = ["SOLUTION_TYPE_CHAT"] + } + } + engines_configs = { + my-chat-engine = { + data_store_ids = [ + "data-store-1", + "data-store-2", + "projects/my-project/locations/global/collections/default_collection/dataStores/data-store-3" + ] + chat_engine_config = { + company_name = "Google" + default_language_code = "en" + time_zone = "America/Los_Angeles" + } + } + } +} +# tftest modules=1 resources=3 +``` + +### Set data store schemas + +You can configure JSON data store schema definitions directly in your data store configuration. + +```hcl +module "agentspace" { + source = "./fabric/modules/agentspace" + name = "my-search-app" + project_id = var.project_id + data_stores_configs = { + data-store-1 = { + json_schema = "{\"$schema\":\"https://json-schema.org/draft/2020-12/schema\",\"datetime_detection\":true,\"type\":\"object\",\"geolocation_detection\":true}" + solution_types = ["SOLUTION_TYPE_SEARCH"] + } + } +} +# tftest modules=1 resources=2 +``` + +### Back data stores with websites data + +You can make data stores point to multiple websites and optionally specify their sitemap. + +```hcl +module "agentspace" { + source = "./fabric/modules/agentspace" + name = "my-search-app" + project_id = var.project_id + data_stores_configs = { + website-search-ds = { + solution_types = ["SOLUTION_TYPE_SEARCH"] + sites_search_config = { + sitemap_uri = "https://cloud.google.com/sitemap.xml" + target_sites = { + include-google-docs = { + provided_uri_pattern = "cloud.google.com/docs/*" + } + exclude-one-page = { + exact_match = true + provided_uri_pattern = "https://cloud.google.com/agentspace" + type = "EXCLUDE" + } + } + } + } + } + engines_configs = { + my-search-engine = { + data_store_ids = [ + "website-search-ds" + ] + industry_vertical = "GENERIC" + search_engine_config = {} + } + } +} +# tftest modules=1 resources=5 +``` + +## Variables + +| name | description | type | required | default | +|---|---|:---:|:---:|:---:| +| [name](variables.tf#L159) | The name of the resources. | string | ✓ | | +| [project_id](variables.tf#L165) | The ID of the project where the data stores and the agents will be created. | string | ✓ | | +| [data_stores_configs](variables.tf#L17) | The Agentspace datastore configurations. | map(object({…})) | | {} | +| [engines_configs](variables.tf#L112) | The Agentspace engines configurations. | map(object({…})) | | {} | +| [location](variables.tf#L153) | Location where the data stores and agents will be created. | string | | "global" | + +## Outputs + +| name | description | sensitive | +|---|---|:---:| +| [chat_engine_ids](outputs.tf#L17) | The ids of the chat engines created. | | +| [chat_engines](outputs.tf#L25) | The chat engines created. | | +| [data_store_ids](outputs.tf#L30) | The ids of the data stores created. | | +| [data_stores](outputs.tf#L38) | The data stores resources created. | | +| [search_engine_ids](outputs.tf#L43) | The ids of the search engines created. | | +| [search_engines](outputs.tf#L51) | The search engines created. | | + diff --git a/modules/agentspace/engines.tf b/modules/agentspace/engines.tf new file mode 100644 index 000000000..4c84f9b79 --- /dev/null +++ b/modules/agentspace/engines.tf @@ -0,0 +1,94 @@ +/** + * Copyright 2025 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. + */ + +resource "google_discovery_engine_chat_engine" "default" { + for_each = ({ + for k, v in var.engines_configs + : k => v if v.chat_engine_config != null + }) + engine_id = "${var.name}-${each.key}" + display_name = "${var.name}-${each.key}" + collection_id = each.value.collection_id + project = var.project_id + data_store_ids = [ + for ds in each.value.data_store_ids + : coalesce( + try(google_discovery_engine_data_store.default[ds].data_store_id, null), + ds + ) + ] + industry_vertical = coalesce( + try(each.value.industry_vertical, null), + try(google_discovery_engine_data_store.default[each.value.data_store_ids[0]].industry_vertical, null) + ) + location = coalesce( + try(each.value.location, null), + try(google_discovery_engine_data_store.default[each.value.data_store_ids[0]].location, null), + var.location + ) + + chat_engine_config { + allow_cross_region = each.value.chat_engine_config.allow_cross_region + dialogflow_agent_to_link = each.value.chat_engine_config.dialogflow_agent_to_link + + agent_creation_config { + business = each.value.chat_engine_config.business + default_language_code = each.value.chat_engine_config.default_language_code + time_zone = each.value.chat_engine_config.time_zone + location = coalesce( + try(each.value.location, null), + try(google_discovery_engine_data_store.default[each.value.data_store_ids[0]].location, null), + var.location + ) + } + } + + common_config { + company_name = each.value.chat_engine_config.company_name + } +} + +resource "google_discovery_engine_search_engine" "default" { + for_each = ({ + for k, v in var.engines_configs + : k => v if v.search_engine_config != null + }) + engine_id = "${var.name}-${each.key}" + display_name = "${var.name}-${each.key}" + collection_id = each.value.collection_id + project = var.project_id + data_store_ids = [ + for ds in each.value.data_store_ids + : coalesce( + try(google_discovery_engine_data_store.default[ds].data_store_id, null), + ds + ) + ] + industry_vertical = coalesce( + try(each.value.industry_vertical, null), + try(google_discovery_engine_data_store.default[each.value.data_store_ids[0]].industry_vertical, null) + ) + location = coalesce( + try(each.value.location, null), + try(google_discovery_engine_data_store.default[each.value.data_store_ids[0]].location, null), + var.location + ) + + search_engine_config { + search_add_ons = each.value.search_engine_config.search_add_ons + search_tier = each.value.search_engine_config.search_tier + } +} diff --git a/modules/agentspace/main.tf b/modules/agentspace/main.tf new file mode 100644 index 000000000..5ae3d1119 --- /dev/null +++ b/modules/agentspace/main.tf @@ -0,0 +1,194 @@ +/** + * Copyright 2025 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. + */ + +locals { + data_stores_target_sites = { + for item in flatten([ + for data_store_id, data_store_config in var.data_stores_configs : + [ + for target_site_key, target_site_config in try( + data_store_config.sites_search_config.target_sites, {}) : + merge({ + key = "${data_store_id}-${target_site_key}" + data_store_id = data_store_id + }, target_site_config) + ] + ]) : item.key => item + } +} + +resource "google_discovery_engine_data_store" "default" { + for_each = var.data_stores_configs + data_store_id = "${var.name}-${each.key}" + project = var.project_id + location = coalesce(each.value.location, var.location) + display_name = each.value.display_name + industry_vertical = each.value.industry_vertical + content_config = each.value.content_config + solution_types = each.value.solution_types + create_advanced_site_search = each.value.create_advanced_site_search + skip_default_schema_creation = each.value.skip_default_schema_creation + + dynamic "advanced_site_search_config" { + for_each = ( + try(each.value.advanced_site_search_config, null) == null + ? [] : [""] + ) + + content { + disable_initial_index = each.value.advanced_site_search_config.disable_initial_index + disable_automatic_refresh = each.value.advanced_site_search_config.disable_automatic_refresh + } + } + + dynamic "document_processing_config" { + for_each = ( + try(each.value.document_processing_config, null) == null + ? [] : [""] + ) + + content { + dynamic "chunking_config" { + for_each = ( + try(each.value.document_processing_config.chunking_config, null) == null + ? [] : [""] + ) + + content { + dynamic "layout_based_chunking_config" { + for_each = ( + try(each.value.document_processing_config.chunking_config.layout_based_chunking_config, null) == null + ? [] : [""] + ) + + content { + chunk_size = each.value.document_processing_config.chunking_config.layout_based_chunking_config.chunk_size + include_ancestor_headings = each.value.document_processing_config.chunking_config.layout_based_chunking_config.include_ancestor_headings + } + } + } + } + + dynamic "default_parsing_config" { + for_each = ( + try(each.value.document_processing_config.default_parsing_config, null) == null + ? [] : [""] + ) + + content { + dynamic "digital_parsing_config" { + for_each = ( + try(each.value.document_processing_config.default_parsing_config.digital_parsing_config, null) == null + ? [] : [""] + ) + + content {} + } + + dynamic "layout_parsing_config" { + for_each = ( + try(each.value.document_processing_config.default_parsing_config.layout_parsing_config, null) == null + ? [] : [""] + ) + + content {} + } + + dynamic "ocr_parsing_config" { + for_each = ( + try(each.value.document_processing_config.default_parsing_config.ocr_parsing_config, null) == null + ? [] : [""] + ) + + content { + use_native_text = each.value.document_processing_config.default_parsing_config.ocr_parsing_config.use_native_text + } + } + } + } + + dynamic "parsing_config_overrides" { + for_each = each.value.document_processing_config.parsing_config_overrides + + content { + file_type = parsing_config_overrides.key + + dynamic "digital_parsing_config" { + for_each = ( + try(parsing_config_overrides.value["digital_parsing_config"], null) == null + ? [] : [""] + ) + + content {} + } + + dynamic "layout_parsing_config" { + for_each = ( + try(parsing_config_overrides.value["layout_parsing_config"], null) == null + ? [] : [""] + ) + + content {} + } + + dynamic "ocr_parsing_config" { + for_each = ( + try(parsing_config_overrides.value["ocr_parsing_config"], null) == null + ? [] : [""] + ) + + content { + use_native_text = parsing_config_overrides.value["ocr_parsing_config"]["use_native_text"] + } + } + } + } + } + } +} + +resource "google_discovery_engine_schema" "default" { + for_each = ({ + for k, v in var.data_stores_configs + : k => v if try(v.json_schema, null) != null + }) + schema_id = "${var.name}-${each.key}" + project = var.project_id + location = google_discovery_engine_data_store.default[each.key].location + data_store_id = google_discovery_engine_data_store.default[each.key].data_store_id + json_schema = each.value.json_schema +} + +resource "google_discovery_engine_sitemap" "default" { + for_each = ({ + for k, v in var.data_stores_configs + : k => v if try(v.sites_search_config.sitemap_uri, null) != null + }) + project = var.project_id + location = google_discovery_engine_data_store.default[each.key].location + data_store_id = google_discovery_engine_data_store.default[each.key].data_store_id + uri = each.value.sites_search_config.sitemap_uri +} + +resource "google_discovery_engine_target_site" "default" { + for_each = local.data_stores_target_sites + project = var.project_id + location = google_discovery_engine_data_store.default[each.value.data_store_id].location + data_store_id = google_discovery_engine_data_store.default[each.value.data_store_id].data_store_id + provided_uri_pattern = each.value.provided_uri_pattern + type = each.value.type + exact_match = each.value.exact_match +} diff --git a/modules/agentspace/outputs.tf b/modules/agentspace/outputs.tf new file mode 100644 index 000000000..10ca868b7 --- /dev/null +++ b/modules/agentspace/outputs.tf @@ -0,0 +1,54 @@ +/** + * Copyright 2024 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. + */ + +output "chat_engine_ids" { + description = "The ids of the chat engines created." + value = { + for k, v in google_discovery_engine_chat_engine.default + : k => v.id + } +} + +output "chat_engines" { + description = "The chat engines created." + value = google_discovery_engine_chat_engine.default +} + +output "data_store_ids" { + description = "The ids of the data stores created." + value = { + for k, v in google_discovery_engine_data_store.default + : k => v.id + } +} + +output "data_stores" { + description = "The data stores resources created." + value = google_discovery_engine_data_store.default +} + +output "search_engine_ids" { + description = "The ids of the search engines created." + value = { + for k, v in google_discovery_engine_search_engine.default + : k => v.id + } +} + +output "search_engines" { + description = "The search engines created." + value = google_discovery_engine_search_engine.default +} diff --git a/modules/agentspace/variables.tf b/modules/agentspace/variables.tf new file mode 100644 index 000000000..8adbd96f1 --- /dev/null +++ b/modules/agentspace/variables.tf @@ -0,0 +1,169 @@ +/** + * Copyright 2025 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. + */ + +variable "data_stores_configs" { + description = "The Agentspace datastore configurations." + type = map(object({ + advanced_site_search_config = optional(object({ + disable_initial_index = optional(bool) + disable_automatic_refresh = optional(bool) + })) + content_config = optional(string, "NO_CONTENT") + create_advanced_site_search = optional(bool) + display_name = optional(string, "Terraform managed.") + document_processing_config = optional(object({ + chunking_config = optional(object({ + layout_based_chunking_config = optional(object({ + chunk_size = optional(number) + include_ancestor_headings = optional(bool) + })) + })) + default_parsing_config = optional(object({ + digital_parsing_config = optional(bool) + layout_parsing_config = optional(bool) + ocr_parsing_config = optional(object({ + use_native_text = optional(bool) + })) + })) + # Accepted keys: docx, html, pdf + parsing_config_overrides = map(object({ + digital_parsing_config = optional(bool) + layout_parsing_config = optional(bool) + ocr_parsing_config = optional(object({ + use_native_text = optional(bool) + })) + })) + })) + industry_vertical = optional(string, "GENERIC") + json_schema = optional(string) + location = optional(string) + skip_default_schema_creation = optional(bool) + solution_types = optional(list(string)) + sites_search_config = optional(object({ + sitemap_uri = optional(string) + target_sites = map(object({ + provided_uri_pattern = string + exact_match = optional(bool, false) + type = optional(string, "INCLUDE") + })) + })) + })) + nullable = false + default = {} + validation { + condition = try(contains( + ["CONTENT_REQUIRED", "NO_CONTENT", "PUBLIC_WEBSITE"], + var.data_stores_configs.content_config + ), true) + error_message = "data_store_configs.content_config must be one or more of [CONTENT_REQUIRED, NO_CONTENT, PUBLIC_WEBSITE]." + } + validation { + condition = try(contains( + ["GENERIC", "HEALTHCARE_FHIR", "MEDIA"], + var.data_stores_configs.industry_vertical + ), true) + error_message = "data_store_configs.industry_vertical must be one or more of [GENERIC, HEALTHCARE_FHIR, MEDIA]." + } + validation { + condition = alltrue([ + for st in try(var.data_stores_configs.solution_types, []) + : contains([ + "SOLUTION_TYPE_CHAT", + "SOLUTION_TYPE_GENERATIVE_CHAT", + "SOLUTION_TYPE_RECOMMENDATION", + "SOLUTION_TYPE_SEARCH" + ], st) + ]) + error_message = "data_store_configs.solution_types must be one or more of [SOLUTION_TYPE_CHAT, SOLUTION_TYPE_GENERATIVE_CHAT, SOLUTION_TYPE_RECOMMENDATION, SOLUTION_TYPE_SEARCH]." + } + validation { + condition = alltrue([ + for k, _ in try(var.data_stores_configs.document_processing_config.parsing_config_overrides, {}) + : contains([ + "docx", + "html", + "pdf" + ], k) + ]) + error_message = "keys in var.data_stores_configs.document_processing_config.parsing_config_overrides must be one of [docx, html, pdf]." + } + validation { + condition = try(contains( + ["EXCLUDE", "INCLUDE"], + var.data_stores_configs.target_site_config + ), true) + error_message = "data_store_configs.target_site_config must be one or more of [EXCLUDE, INCLUDE]." + } +} + +variable "engines_configs" { + description = "The Agentspace engines configurations." + type = map(object({ + data_store_ids = list(string) + collection_id = optional(string, "default_collection") + chat_engine_config = optional(object({ + allow_cross_region = optional(bool) + business = optional(string) + company_name = optional(string) + default_language_code = optional(string) + dialogflow_agent_to_link = optional(string) + time_zone = optional(string) + })) + # If industry_vertical and location are not given, + # they are derived from the first datastore attached + # to the engines + industry_vertical = optional(string) + location = optional(string) + search_engine_config = optional(object({ + search_add_ons = optional(list(string), []) + search_tier = optional(string) + })) + })) + nullable = false + default = {} + validation { + condition = alltrue([ + for ao in try(var.engines_configs.search_engine_config.search_add_ons, []) + : contains(["SEARCH_ADD_ON_LLM"], ao) + ]) + error_message = "Elements in engines_configs.search_engine_config.search_add_ons must be one or more of [SEARCH_ADD_ON_LLM]." + } + validation { + condition = try(contains( + ["SEARCH_TIER_ENTERPRISE", "SEARCH_TIER_STANDARD"], + var.engines_configs.search_engine_config.search_tier + ), true) + error_message = "engines_configs.search_engine_config.search_tier must be one of [SEARCH_TIER_ENTERPRISE, SEARCH_TIER_STANDARD]." + } +} + +variable "location" { + description = "Location where the data stores and agents will be created." + type = string + default = "global" +} + +variable "name" { + description = "The name of the resources." + type = string + nullable = false +} + +variable "project_id" { + description = "The ID of the project where the data stores and the agents will be created." + type = string + nullable = false +} diff --git a/modules/agentspace/versions.tf b/modules/agentspace/versions.tf new file mode 100644 index 000000000..00cfef9d6 --- /dev/null +++ b/modules/agentspace/versions.tf @@ -0,0 +1,35 @@ +# Copyright 2025 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 +# +# https://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. + +# Fabric release: 40.1.0 + +terraform { + required_version = ">= 1.11.4" + required_providers { + google = { + source = "hashicorp/google" + version = ">= 6.33.0, < 7.0.0" # tftest + } + google-beta = { + source = "hashicorp/google-beta" + version = ">= 6.33.0, < 7.0.0" # tftest + } + } + provider_meta "google" { + module_name = "google-pso-tool/cloud-foundation-fabric/modules/alloydb:40.1.0-tf" + } + provider_meta "google-beta" { + module_name = "google-pso-tool/cloud-foundation-fabric/modules/alloydb:40.1.0-tf" + } +} diff --git a/modules/agentspace/versions.tofu b/modules/agentspace/versions.tofu new file mode 100644 index 000000000..b87d6d775 --- /dev/null +++ b/modules/agentspace/versions.tofu @@ -0,0 +1,35 @@ +# Copyright 2025 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 +# +# https://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. + +# Fabric release: 40.1.0 + +terraform { + required_version = ">= 1.9.0" + required_providers { + google = { + source = "hashicorp/google" + version = ">= 6.33.0, < 7.0.0" # tftest + } + google-beta = { + source = "hashicorp/google-beta" + version = ">= 6.33.0, < 7.0.0" # tftest + } + } + provider_meta "google" { + module_name = "google-pso-tool/cloud-foundation-fabric/modules/alloydb:40.1.0-tofu" + } + provider_meta "google-beta" { + module_name = "google-pso-tool/cloud-foundation-fabric/modules/alloydb:40.1.0-tofu" + } +}