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"
+ }
+}