Update ai-applications module to support dialogflow-cx (fully capability and regional) agents
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2025 Google LLC
|
||||
* 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.
|
||||
@@ -14,6 +14,294 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "chat_agent_security_configs" {
|
||||
description = "The DLP security configurations for (Dialogflow CX) chat agents."
|
||||
type = object({
|
||||
audio_export_settings = optional(object({
|
||||
# AUDIO_FORMAT_UNSPECIFIED, MULAW, MP3, OGG
|
||||
audio_format = string
|
||||
gcs_bucket_config = object({
|
||||
# specify an id to use an existing GCS bucket
|
||||
id = optional(string)
|
||||
prefix = string
|
||||
location = optional(string)
|
||||
name = optional(string)
|
||||
versioning = optional(bool, true)
|
||||
})
|
||||
audio_export_pattern = string
|
||||
enable_audio_redaction = optional(bool, false)
|
||||
}))
|
||||
dlp_deidentify_template = optional(object({
|
||||
description = optional(string, "Terraform managed.")
|
||||
display_name = optional(string)
|
||||
info_type_transformations = optional(object({
|
||||
transformations = list(object({
|
||||
info_types = optional(list(object({
|
||||
name = string
|
||||
version = optional(string)
|
||||
sensitivity_score = optional(string)
|
||||
})))
|
||||
primitive_transformation = any
|
||||
}))
|
||||
}))
|
||||
parent = optional(string)
|
||||
record_transformations = optional(object({
|
||||
field_transformations = optional(list(object({
|
||||
fields = list(object({ name = string }))
|
||||
condition = optional(object({
|
||||
expressions = optional(object({
|
||||
logical_operator = optional(string)
|
||||
conditions = list(object({
|
||||
field = object({ name = string })
|
||||
operator = string
|
||||
value = optional(object({
|
||||
integer_value = optional(number)
|
||||
float_value = optional(number)
|
||||
string_value = optional(string)
|
||||
boolean_value = optional(bool)
|
||||
timestamp_value = optional(string)
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
primitive_transformation = optional(object({
|
||||
replace_config = optional(object({
|
||||
new_value = object({
|
||||
integer_value = optional(number)
|
||||
float_value = optional(number)
|
||||
string_value = optional(string)
|
||||
boolean_value = optional(bool)
|
||||
timestamp_value = optional(string)
|
||||
time_value = optional(object({
|
||||
hours = optional(number)
|
||||
minutes = optional(number)
|
||||
seconds = optional(number)
|
||||
nanos = optional(number)
|
||||
}))
|
||||
date_value = optional(object({
|
||||
year = optional(number)
|
||||
month = optional(number)
|
||||
day = optional(number)
|
||||
}))
|
||||
day_of_week_value = optional(string)
|
||||
})
|
||||
}))
|
||||
character_mask_config = optional(object({
|
||||
masking_character = optional(string)
|
||||
number_to_mask = optional(number)
|
||||
reverse_order = optional(bool)
|
||||
characters_to_ignore = optional(object({
|
||||
characters_to_skip = optional(string)
|
||||
common_characters_to_ignore = optional(string)
|
||||
}))
|
||||
}))
|
||||
crypto_replace_ffx_fpe_config = optional(object({
|
||||
crypto_key = optional(object({
|
||||
transient = optional(object({ name = string }))
|
||||
unwrapped = optional(object({ key = string }))
|
||||
kms_wrapped = optional(object({ wrapped_key = string, crypto_key_name = string }))
|
||||
}))
|
||||
context = optional(object({ name = optional(string) }))
|
||||
surrogate_info_type = optional(object({
|
||||
name = optional(string)
|
||||
version = optional(string)
|
||||
sensitivity_score = optional(string)
|
||||
}))
|
||||
common_alphabet = optional(string)
|
||||
custom_alphabet = optional(string)
|
||||
radix = optional(number)
|
||||
}))
|
||||
# I'll use 'any' for the rest of primitive transformations here to keep it within reason,
|
||||
# as they are less common in field transformations compared to masking/redaction/replacement.
|
||||
# Actually, let's just include them as 'any' to save space but allow them.
|
||||
crypto_deterministic_config = optional(any)
|
||||
replace_dictionary_config = optional(any)
|
||||
date_shift_config = optional(any)
|
||||
fixed_size_bucketing_config = optional(any)
|
||||
bucketing_config = optional(any)
|
||||
time_part_config = optional(any)
|
||||
redact_config = optional(bool)
|
||||
crypto_hash_config = optional(any)
|
||||
}))
|
||||
info_type_transformations = optional(object({
|
||||
transformations = list(object({
|
||||
info_types = optional(list(object({
|
||||
name = string
|
||||
version = optional(string)
|
||||
sensitivity_score = optional(string)
|
||||
})))
|
||||
primitive_transformation = optional(any)
|
||||
}))
|
||||
}))
|
||||
})))
|
||||
record_suppressions = optional(list(object({
|
||||
condition = optional(object({
|
||||
expressions = optional(object({
|
||||
logical_operator = optional(string)
|
||||
conditions = list(object({
|
||||
field = object({ name = string })
|
||||
operator = string
|
||||
value = optional(object({
|
||||
integer_value = optional(number)
|
||||
float_value = optional(number)
|
||||
string_value = optional(string)
|
||||
boolean_value = optional(bool)
|
||||
timestamp_value = optional(string)
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
})))
|
||||
}))
|
||||
template_id = optional(string)
|
||||
}))
|
||||
dlp_inspect_template = optional(object({
|
||||
# ["CONTENT_TEXT", "CONTENT_IMAGE"]
|
||||
content_options = optional(list(string), [])
|
||||
custom_info_types = optional(map(object({
|
||||
dictionary = optional(object({
|
||||
cloud_storage_path = optional(string)
|
||||
words_list = optional(list(string))
|
||||
}))
|
||||
# null or EXCLUSION_TYPE_EXCLUDE
|
||||
exclusion_type = optional(string)
|
||||
# SENSITIVITY_LOW, SENSITIVITY_MODERATE, SENSITIVITY_HIGH
|
||||
# VERY_UNLIKELY, UNLIKELY, POSSIBLE, LIKELY, VERY_LIKELY
|
||||
likelihood = optional(string, "VERY_LIKELY")
|
||||
regex = optional(object({
|
||||
# https://github.com/google/re2/wiki/Syntax
|
||||
pattern = string
|
||||
group_indexes = optional(list(number))
|
||||
}))
|
||||
sensitivity_score = optional(string)
|
||||
stored_type_name = optional(string)
|
||||
surrogate_type = optional(string)
|
||||
version = optional(string)
|
||||
})))
|
||||
description = optional(string, "Terraform managed.")
|
||||
exclude_info_types = optional(bool, false)
|
||||
include_quote = optional(bool, false)
|
||||
# name is the key
|
||||
# https://cloud.google.com/dlp/docs/infotypes-reference
|
||||
info_types = optional(map(object({
|
||||
# SENSITIVITY_LOW, SENSITIVITY_MODERATE, SENSITIVITY_HIGH
|
||||
sensitivity_score = optional(string, "SENSITIVITY_MODERATE")
|
||||
version = optional(string)
|
||||
})), {})
|
||||
limits = optional(object({
|
||||
max_findings_per_item = optional(number, 2000)
|
||||
max_findings_per_request = optional(number, 2000)
|
||||
# key is the name of the info type
|
||||
# https://cloud.google.com/dlp/docs/infotypes-reference
|
||||
max_findings_per_info_type = optional(map(object({
|
||||
max_findings = optional(number, 2000)
|
||||
# SENSITIVITY_LOW, SENSITIVITY_MODERATE, SENSITIVITY_HIGH
|
||||
sensitivity_score = optional(string, "SENSITIVITY_MODERATE")
|
||||
version = optional(string)
|
||||
})))
|
||||
}))
|
||||
# VERY_UNLIKELY, UNLIKELY, POSSIBLE, LIKELY, VERY_LIKELY
|
||||
min_likelihood = optional(string, "POSSIBLE")
|
||||
name = optional(string)
|
||||
parent = optional(string)
|
||||
rule_sets = optional(map(object({
|
||||
# name is the key
|
||||
# https://cloud.google.com/dlp/docs/infotypes-reference
|
||||
info_types = map(object({
|
||||
version = optional(string)
|
||||
# SENSITIVITY_LOW, SENSITIVITY_MODERATE, SENSITIVITY_HIGH
|
||||
sensitivity_score = optional(string, "SENSITIVITY_MODERATE")
|
||||
}))
|
||||
rules = object({
|
||||
exclusion_rule = optional(object({
|
||||
# MATCHING_TYPE_FULL_MATCH, MATCHING_TYPE_PARTIAL_MATCH, MATCHING_TYPE_INVERSE_MATCH
|
||||
# https://cloud.google.com/dlp/docs/reference/rest/v2/InspectConfig#MatchingType
|
||||
matching_type = string
|
||||
dictionary = optional(object({
|
||||
cloud_storage_path = optional(string)
|
||||
words_list = optional(list(string))
|
||||
}))
|
||||
regex = optional(object({
|
||||
# https://github.com/google/re2/wiki/Syntax
|
||||
pattern = string
|
||||
group_indexes = optional(list(number))
|
||||
}))
|
||||
}))
|
||||
hotword_rule = optional(object({
|
||||
hotword_regex = object({
|
||||
pattern = string
|
||||
group_indexes = optional(list(number))
|
||||
})
|
||||
proximity = object({
|
||||
# Either window_before or window_after must be specified
|
||||
window_after = optional(number)
|
||||
window_before = optional(number)
|
||||
})
|
||||
likelihood_adjustment = optional(object({
|
||||
fixed_likelihood = optional(string)
|
||||
relative_likelihood = optional(number)
|
||||
}))
|
||||
}))
|
||||
})
|
||||
})), {})
|
||||
# [a-zA-Z\d-_]+. The maximum length is 100 characters.
|
||||
# Auto-generated if null.
|
||||
template_id = optional(string)
|
||||
}))
|
||||
enable_insights_export = optional(bool, false)
|
||||
location = optional(string)
|
||||
purge_data_types = optional(list(string))
|
||||
redaction_scope = optional(string)
|
||||
redaction_strategy = optional(string)
|
||||
retention_window_days = optional(number)
|
||||
})
|
||||
nullable = false
|
||||
default = {}
|
||||
validation {
|
||||
condition = try(var.chat_agent_security_configs.dlp_inspect_template.min_likelihood == null ? true : contains(
|
||||
["VERY_UNLIKELY", "UNLIKELY", "POSSIBLE", "LIKELY", "VERY_LIKELY"],
|
||||
var.chat_agent_security_configs.dlp_inspect_template.min_likelihood
|
||||
), true)
|
||||
error_message = "inspect_template.min_likelihood must be one of [VERY_UNLIKELY, UNLIKELY, POSSIBLE, LIKELY, VERY_LIKELY]."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for k, v in try(var.chat_agent_security_configs.dlp_inspect_template.custom_info_types, {}) : v.likelihood == null ? true : contains(
|
||||
["VERY_UNLIKELY", "UNLIKELY", "POSSIBLE", "LIKELY", "VERY_LIKELY"],
|
||||
v.likelihood
|
||||
)
|
||||
])
|
||||
error_message = "inspect_template.custom_info_types.*.likelihood must be one of [VERY_UNLIKELY, UNLIKELY, POSSIBLE, LIKELY, VERY_LIKELY]."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for k, v in try(var.chat_agent_security_configs.dlp_inspect_template.rule_sets, {}) : try(v.rules.exclusion_rule.matching_type == null ? true : contains(
|
||||
["MATCHING_TYPE_FULL_MATCH", "MATCHING_TYPE_PARTIAL_MATCH", "MATCHING_TYPE_INVERSE_MATCH"],
|
||||
v.rules.exclusion_rule.matching_type
|
||||
), true)
|
||||
])
|
||||
error_message = "inspect_template.rule_sets.*.rules.exclusion_rule.matching_type must be one of [MATCHING_TYPE_FULL_MATCH, MATCHING_TYPE_PARTIAL_MATCH, MATCHING_TYPE_INVERSE_MATCH]."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for k, v in try(var.chat_agent_security_configs.dlp_inspect_template.custom_info_types, {}) : v.exclusion_type == null ? true : contains(
|
||||
["EXCLUSION_TYPE_EXCLUDE"],
|
||||
v.exclusion_type
|
||||
)
|
||||
])
|
||||
error_message = "inspect_template.custom_info_types.*.exclusion_type must be EXCLUSION_TYPE_EXCLUDE."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for k, v in try(var.chat_agent_security_configs.dlp_inspect_template.info_types, {}) : v.sensitivity_score == null ? true : contains(
|
||||
["SENSITIVITY_LOW", "SENSITIVITY_MODERATE", "SENSITIVITY_HIGH"],
|
||||
v.sensitivity_score
|
||||
)
|
||||
])
|
||||
error_message = "inspect_template.info_types.*.sensitivity_score must be one of [SENSITIVITY_LOW, SENSITIVITY_MODERATE, SENSITIVITY_HIGH]."
|
||||
}
|
||||
}
|
||||
|
||||
variable "data_stores_configs" {
|
||||
description = "The ai-applications datastore configurations."
|
||||
type = map(object({
|
||||
@@ -64,76 +352,109 @@ variable "data_stores_configs" {
|
||||
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]."
|
||||
condition = alltrue([
|
||||
for k, v in var.data_stores_configs : contains(
|
||||
["CONTENT_REQUIRED", "NO_CONTENT", "PUBLIC_WEBSITE"],
|
||||
v.content_config
|
||||
)
|
||||
])
|
||||
error_message = "data_store_configs.content_config must be one of [CONTENT_REQUIRED, NO_CONTENT, PUBLIC_WEBSITE]."
|
||||
}
|
||||
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)
|
||||
for k, v in var.data_stores_configs : contains(
|
||||
["GENERIC", "HEALTHCARE_FHIR", "MEDIA"],
|
||||
v.industry_vertical
|
||||
)
|
||||
])
|
||||
error_message = "data_store_configs.industry_vertical must be one of [GENERIC, HEALTHCARE_FHIR, MEDIA]."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue(flatten([
|
||||
for k, v in var.data_stores_configs : [
|
||||
for st in try(v.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)
|
||||
])
|
||||
condition = alltrue(flatten([
|
||||
for k, v in var.data_stores_configs : [
|
||||
for po_k, po_v in try(v.document_processing_config.parsing_config_overrides, {}) : contains([
|
||||
"docx",
|
||||
"html",
|
||||
"pdf"
|
||||
], po_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]."
|
||||
condition = alltrue(flatten([
|
||||
for k, v in var.data_stores_configs : [
|
||||
for ts_k, ts_v in try(v.sites_search_config.target_sites, {}) : contains([
|
||||
"EXCLUDE",
|
||||
"INCLUDE"
|
||||
], ts_v.type)
|
||||
]
|
||||
]))
|
||||
error_message = "data_store_configs.sites_search_config.target_sites.*.type must be one of [EXCLUDE, INCLUDE]."
|
||||
}
|
||||
}
|
||||
|
||||
variable "engines_configs" {
|
||||
description = "The ai-applications engines configurations."
|
||||
type = map(object({
|
||||
data_store_ids = list(string)
|
||||
collection_id = optional(string, "default_collection")
|
||||
description = "The AI applications engines configurations."
|
||||
type = object({
|
||||
chat_engine_config = optional(object({
|
||||
allow_cross_region = optional(bool, null)
|
||||
business = optional(string)
|
||||
company_name = optional(string)
|
||||
default_language_code = optional(string)
|
||||
dialogflow_agent_to_link = optional(string)
|
||||
time_zone = optional(string)
|
||||
agent_config = optional(object({
|
||||
avatar_uri = optional(string)
|
||||
default_language_code = optional(string)
|
||||
description = optional(string, "Terraform managed.")
|
||||
# Id of an existing agent. The agent will be created otherwise.
|
||||
id = optional(string)
|
||||
# This overrides the engine location,
|
||||
# the datastores location and var.location
|
||||
location = optional(string)
|
||||
security_settings_config = optional(object({
|
||||
create = optional(bool, false)
|
||||
id = optional(string)
|
||||
}))
|
||||
supported_language_codes = optional(list(string))
|
||||
time_zone = optional(string)
|
||||
}), {})
|
||||
allow_cross_region = optional(bool, true)
|
||||
business = optional(string)
|
||||
company_name = optional(string)
|
||||
}))
|
||||
collection_id = optional(string, "default_collection")
|
||||
data_store_ids = optional(list(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)
|
||||
# This can override var.location and the datastores location
|
||||
location = optional(string)
|
||||
search_engine_config = optional(object({
|
||||
search_add_ons = optional(list(string), [])
|
||||
search_tier = optional(string)
|
||||
}))
|
||||
}))
|
||||
})
|
||||
nullable = false
|
||||
default = {}
|
||||
validation {
|
||||
condition = (
|
||||
var.engines_configs.chat_engine_config == null
|
||||
&& var.engines_configs.search_engine_config == null
|
||||
? true
|
||||
: length(var.engines_configs.data_store_ids) > 0 ? true : false
|
||||
)
|
||||
error_message = "You must specify at least one data store id for each engine."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for ao in try(var.engines_configs.search_engine_config.search_add_ons, [])
|
||||
@@ -142,10 +463,13 @@ variable "engines_configs" {
|
||||
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)
|
||||
condition = alltrue([
|
||||
try(var.engines_configs.search_engine_config.search_tier, null) == null
|
||||
? true : 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]."
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user