variable.sql.tf (579 lines of code) (raw):

variable "sql_dedicated_gateway" { type = object({ instance_size = string instance_count = optional(number, 1) }) default = null description = <<DESCRIPTION Defaults to `null`. Manages a SQL Dedicated Gateway within a Cosmos DB Account. - `instance_size` - (Optional) - The instance size for the CosmosDB SQL Dedicated Gateway. Changing this forces a new resource to be created. Possible values are `Cosmos.D4s`, `Cosmos.D8s` and `Cosmos.D16s` - `instance_count` - (Optional) - The instance count for the CosmosDB SQL Dedicated Gateway. Possible value is between `1` and `5`. > Note: To create a dedicated gateway in a zone redundant region you must request Azure to enable it into your account. See more in: https://learn.microsoft.com/en-us/azure/cosmos-db/dedicated-gateway#provisioning-the-dedicated-gateway Example inputs: ```hcl sql_dedicated_gateway = { instance_count = 1 instance_size = "Cosmos.D4s" } ``` DESCRIPTION validation { condition = try(var.sql_dedicated_gateway.instance_count, null) != null ? var.sql_dedicated_gateway.instance_count >= 1 && var.sql_dedicated_gateway.instance_count <= 5 : true error_message = "The 'instance_count' in the sql_dedicated_gateway value must be between 1 and 5 if specified." } validation { condition = try(var.sql_dedicated_gateway.instance_size, null) != null ? can(index(["Cosmos.D4s", "Cosmos.D8s", "Cosmos.D16s"], var.sql_dedicated_gateway.instance_size)) : true error_message = "The 'instance_size' in the sql_dedicated_gateway value must be 'Cosmos.D4s', 'Cosmos.D8s' or 'Cosmos.D16s' if specified." } } variable "sql_databases" { type = map(object({ name = string throughput = optional(number, null) autoscale_settings = optional(object({ max_throughput = number }), null) containers = optional(map(object({ partition_key_paths = list(string) name = string throughput = optional(number, null) default_ttl = optional(number, null) analytical_storage_ttl = optional(number, null) unique_keys = optional(list(object({ paths = set(string) })), []) autoscale_settings = optional(object({ max_throughput = number }), null) functions = optional(map(object({ body = string name = string })), {}) stored_procedures = optional(map(object({ body = string name = string })), {}) triggers = optional(map(object({ body = string type = string operation = string name = string })), {}) conflict_resolution_policy = optional(object({ mode = string conflict_resolution_path = optional(string, null) conflict_resolution_procedure = optional(string, null) }), null) indexing_policy = optional(object({ indexing_mode = string included_paths = optional(set(object({ path = string })), []) excluded_paths = optional(set(object({ path = string })), []) composite_indexes = optional(set(object({ indexes = set(object({ path = string order = string })) })), []) spatial_indexes = optional(set(object({ path = string })), []) }), null) })), {}) })) nullable = false default = {} description = <<DESCRIPTION Defaults to `{}`. Manages SQL Databases within a Cosmos DB Account. - `name` - (Required) - Specifies the name of the Cosmos DB SQL Container. Changing this forces a new resource to be created. - `throughput` - (Optional) - Defaults to `null`. The throughput of SQL database (RU/s). Must be set in increments of `100`. The minimum value is `400`. This must be set upon database creation otherwise it cannot be updated without a manual terraform destroy-apply. - `autoscale_settings` - (Optional) - Defaults to `null`. This must be set upon database creation otherwise it cannot be updated without a manual terraform destroy-apply. - `max_throughput` - (Required) - The maximum throughput of the SQL database (RU/s). Must be between `1,000` and `1,000,000`. Must be set in increments of `1,000`. Conflicts with `throughput`. - `containers` - (Optional) - Defaults to `{}`. Manages SQL Containers within a Cosmos DB Account. - `partition_key_paths` - (Required) - Defines the partition key for the container. Changing this forces a new resource to be created. - `name` - (Required) - Specifies the name of the Cosmos DB SQL Container. Changing this forces a new resource to be created. - `throughput` - (Optional) - Defaults to `null`. The throughput of SQL container (RU/s). Must be set in increments of `100`. The minimum value is `400`. This must be set upon container creation otherwise it cannot be updated without a manual terraform destroy-apply. - `default_ttl` - (Optional) - Defaults to `null`. The default time to live of SQL container. If missing, items are not expired automatically. If present and the value is set to `-1`, it is equal to infinity, and items don't expire by default. If present and the value is set to some number n - items will expire n seconds after their last modified time. - `analytical_storage_ttl` - (Optional) - Defaults to `null`. The default time to live of Analytical Storage for this SQL container. If present and the value is set to `-1`, it is equal to infinity, and items don't expire by default. If present and the value is set to some number n - items will expire n seconds after their last modified time. - `unique_keys` - (Optional) - Defaults to `[]`. The unique keys of the container. - `paths` - (Required) - A list of paths to use for this unique key. Changing this forces a new resource to be created. - `autoscale_settings` - (Optional) - Defaults to `null`. This must be set upon database creation otherwise it cannot be updated without a manual terraform destroy-apply. - `max_throughput` - (Required) - The maximum throughput of the SQL container (RU/s). Must be between `1,000` and `1,000,000`. Must be set in increments of `1,000`. Conflicts with `throughput`. - `functions` - (Optional) - Defaults to `{}`. Manages SQL User Defined Functions. - `body` - (Required) - Body of the User Defined Function. - `name` - (Required) - The name which should be used for this SQL User Defined Function. Changing this forces a new SQL User Defined Function to be created. - `stored_procedures` - (Optional) - Defaults to `{}`. Manages SQL Stored Procedures within a Cosmos DB Account SQL Database. - `body` - (Required) - The body of the stored procedure. - `name` - (Required) - Specifies the name of the Cosmos DB SQL Stored Procedure. Changing this forces a new resource to be created. - `triggers` - (Optional) - Defaults to `{}`. Manages SQL Triggers. - `body` - (Required) - Body of the Trigger. - `type` - (Required) - Type of the Trigger. Possible values are `Pre` and `Post`. - `operation` - (Required) - The operation the trigger is associated with. Possible values are `All`, `Create`, `Update`, `Delete` and `Replace`. - `name` - (Required) - The name which should be used for this SQL Trigger. Changing this forces a new SQL Trigger to be created. - `conflict_resolution_policy` - (Optional) - Defaults to `null`. The conflict resolution policy of the container. Changing this forces a new resource to be created. - `mode` - (Required) - Indicates the conflict resolution mode. Possible values include: `LastWriterWins` and `Custom`. - `conflict_resolution_path` - Required if `LastWriterWins` is set as `mode` - The conflict resolution path. - `conflict_resolution_procedure` - Required if `Custom` is set as `mode` - The procedure to resolve conflicts . - `indexing_policy` - (Optional) - Defaults to `{}`. The indexing policy of the container. - `indexing_mode` - (Required) - Indicates the indexing mode. Possible values include: `consistent` and `none` - `included_paths` - (Optional) - Defaults to `[]`. Either included_path or excluded_path must contain the path `/*` - `path` - (Required) - Path for which the indexing behaviour applies to. - `excluded_paths` - (Optional) - Defaults to `[]`. Either included_path or excluded_path must contain the path `/*` - `path` - (Required) - Path that is excluded from indexing. - `composite_indexes` - (Optional) - Defaults to `[]`. The composite indexes of the indexing policy. - `indexes` - (Required) - The indexes of the composite indexes. - `path` - (Required) - Path for which the indexing behaviour applies to. - `order` - (Required) - Order of the index. Possible values are `Ascending` or `Descending`. - `spatial_indexes` - (Optional) - Defaults to `[]`. The spatial indexes of the indexing policy. - `path` - (Required) - Path for which the indexing behaviour applies to. According to the service design, all spatial types including LineString, MultiPolygon, Point, and Polygon will be applied to the path. > Note: Switching between autoscale and manual throughput is not supported via Terraform and must be completed via the Azure Portal and refreshed. > Note: For indexing policy See more in: https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/how-to-manage-indexing-policy?tabs=dotnetv3%2Cpythonv3 Example inputs: ```hcl sql_databases = { database1 = { name = "database1" throughput = 400 # autoscale_settings = { # max_throughput = 4000 # } containers = { container1 = { partition_key_paths = ["/id"] name = "container1" throughput = 400 default_ttl = 1000 analytical_storage_ttl = 1000 unique_keys = [ { paths = ["/field1", "/field2"] } ] # autoscale_settings = { # max_throughput = 4000 # } functions = { function1 = { name = "functionName" body = "function function1() { }" } } stored_procedures = { stored1 = { name = "storedName" body = "function stored1() { }" } } triggers = { trigger1 = { name = "triggerName" body = "function trigger1() { }" type = "Pre" operation = "All" } } conflict_resolution_policy = { mode = "LastWriterWins" conflict_resolution_path = "/customProperty" } indexing_policy = { indexing_mode = "consistent" included_paths = [ { path = "/*" } ] excluded_paths = [ { path = "/excluded/*" } ] composite_indexes = [ { indexes = [ { path = "/field1" order = "ascending" } ] } ] spatial_indexes = [ { path = "/location/*" } ] } } } } } ``` DESCRIPTION validation { condition = length( [ for db_key, db_params in var.sql_databases : db_params.name ]) == length(distinct( [ for db_key, db_params in var.sql_databases : db_params.name ]) ) error_message = "The 'name' in the sql database value must be unique." } validation { condition = alltrue( [ for db_key, db_params in var.sql_databases : length( [ for container_key, container_params in db_params.containers : container_params.name ] ) == length(distinct( [ for container_key, container_params in db_params.containers : container_params.name ] )) ]) error_message = "The 'name' in the sql container value must be unique withing a sql database." } validation { condition = alltrue(flatten( [ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : length( [ for function_key, function_params in container_params.functions : function_params.name ] ) == length(distinct( [ for function_key, function_params in container_params.functions : function_params.name ] )) ] ])) error_message = "The 'name' in the sql function value must be unique within a container." } validation { condition = alltrue(flatten( [ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : length( [ for trigger_key, trigger_params in container_params.triggers : trigger_params.name ] ) == length(distinct( [ for trigger_key, trigger_params in container_params.triggers : trigger_params.name ] )) ] ])) error_message = "The 'name' in the sql triggers value must be unique within a container." } validation { condition = alltrue(flatten( [ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : length( [ for stored_key, stored_params in container_params.stored_procedures : stored_params.name ] ) == length(distinct( [ for stored_key, stored_params in container_params.stored_procedures : stored_params.name ] )) ] ])) error_message = "The 'name' in the sql stored procedure value must be unique within a container." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : length(container_params.partition_key_paths) == 0 ? false : true ] ]) ) error_message = "The 'partition_key_paths' in the containers value must not be empty." } validation { condition = alltrue( [ for key, value in var.sql_databases : try(value.default_ttl, null) != null ? value.default_ttl >= -1 && value.default_ttl <= 2147483647 : true ] ) error_message = "The 'default_ttl' in the database value must be between -1 and 2147483647 if specified." } validation { condition = alltrue( [ for key, value in var.sql_databases : try(value.analytical_storage_ttl, null) != null ? value.analytical_storage_ttl >= -1 && value.analytical_storage_ttl <= 2147483647 : true ] ) error_message = "The 'analytical_storage_ttl' in the database value must be between -1 and 2147483647 if specified." } validation { condition = alltrue( [for key, value in var.sql_databases : value.throughput != null ? value.throughput >= 400 : true] ) error_message = "The 'throughput' in the database value must be greater than or equal to 400 if specified." } validation { condition = alltrue( [ for db_key, db_params in var.sql_databases : db_params.throughput != null ? db_params.throughput % 100 == 0 : true ] ) error_message = "The 'throughput' value in the 'autoscale_settings' at the database level must be a multiple of 100 if specified." } validation { condition = alltrue( [ for key, value in var.sql_databases : try(value.autoscale_settings.max_throughput, null) != null ? value.autoscale_settings.max_throughput >= 1000 && value.autoscale_settings.max_throughput <= 1000000 : true ] ) error_message = "The 'max_throughput' in the autoscale_settings value must be between 1000 and 1000000 if specified." } validation { condition = alltrue( [ for key, value in var.sql_databases : try(value.autoscale_settings.max_throughput, null) != null ? value.autoscale_settings.max_throughput % 1000 == 0 : true ] ) error_message = "The 'max_throughput' in the autoscale_settings value must be a multiple of 1000 if specified." } validation { condition = alltrue( [ for key, value in var.sql_databases : try(value.autoscale_settings.max_throughput, null) != null && value.throughput != null ? false : true ] ) error_message = "The 'throughput' and 'autoscale_settings.max_throughput' cannot be specified at the same time at database level." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : container_params.throughput != null ? container_params.throughput >= 400 : true ] ]) ) error_message = "The 'throughput' value at the container level must be greater than or equal to 400 if specified." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : container_params.throughput != null ? container_params.throughput % 100 == 0 : true ] ]) ) error_message = "The 'throughput' value in the 'autoscale_settings' at the container level must be a multiple of 100 if specified." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : try(container_params.autoscale_settings.max_throughput, null) != null ? container_params.autoscale_settings.max_throughput >= 1000 && container_params.autoscale_settings.max_throughput <= 1000000 : true ] ]) ) error_message = "The 'max_throughput'value in the 'autoscale_settings' at the container level must be between 1000 and 1000000 if specified." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : try(container_params.autoscale_settings.max_throughput, null) != null ? container_params.autoscale_settings.max_throughput % 1000 == 0 : true ] ]) ) error_message = "The 'max_throughput' value in the 'autoscale_settings' at the container level must be a multiple of 1000 if specified." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : try(container_params.autoscale_settings.max_throughput, null) != null && container_params.throughput != null ? false : true ] ]) ) error_message = "The 'throughput' and 'autoscale_settings.max_throughput' cannot be specified at the same time at container level." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : try(container_params.conflict_resolution_policy.mode, null) != null ? contains(["Custom", "LastWriterWins"], container_params.conflict_resolution_policy.mode) : true ] ]) ) error_message = "The 'conflict_resolution_policy.mode' must be either 'Custom' or 'LastWriterWins' if specified." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : try(container_params.conflict_resolution_policy.mode, "") == "LastWriterWins" ? trimspace(try(container_params.conflict_resolution_policy.conflict_resolution_path, "")) != "" : true ] ]) ) error_message = "The 'conflict_resolution_path' must be specified when the conflict resolution mode is 'LastWriterWins'." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : try(container_params.conflict_resolution_policy.mode, "") == "Custom" ? trimspace(try(container_params.conflict_resolution_policy.conflict_resolution_procedure, "")) != "" : true ] ]) ) error_message = "The 'conflict_resolution_procedure' must be specified when the conflict resolution mode is 'Custom'." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : [ for trigger_key, trigger_params in container_params.triggers : contains(["Pre", "Post"], trigger_params.type) ] ] ]) ) error_message = "The 'type' in the trigger value must be either 'Pre' or 'Post'." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : [ for trigger_key, trigger_params in container_params.triggers : contains(["All", "Create", "Delete", "Replace", "Update"], trigger_params.operation) ] ] ]) ) error_message = "The 'operation' in the trigger value must be either 'All', 'Create', 'Delete', 'Replace', or 'Update'." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : [ for trigger_key, trigger_params in container_params.triggers : trimspace(coalesce(trigger_params.body, " ")) != "" ] ] ]) ) error_message = "The 'body' in the trigger value must not be empty." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : [ for function_key, function_params in container_params.functions : trimspace(coalesce(function_params.body, " ")) != "" ] ] ]) ) error_message = "The 'body' in the function value must not be empty." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : [ for stored_key, stored_params in container_params.stored_procedures : trimspace(coalesce(stored_params.body, " ")) != "" ] ] ]) ) error_message = "The 'body' in the stored procedures value must not be empty." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : try(container_params.indexing_policy.indexing_mode, null) != null ? contains(["consistent", "none"], container_params.indexing_policy.indexing_mode) : true ] ]) ) error_message = "The 'indexing_mode' in the indexing_policy value must be either 'consistent' or 'none'." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : [ for composite_index in try(container_params.indexing_policy.composite_indexes, []) : [ for index in composite_index.indexes : contains(["Ascending", "Descending"], index.order) ] ] ] ]) ) error_message = "The 'order' in the composite index value must be either 'Ascending' or 'Descending'." } validation { condition = alltrue( flatten([ for db_key, db_params in var.sql_databases : [ for container_key, container_params in db_params.containers : length(try(container_params.indexing_policy.included_paths, [])) > 0 || length(try(container_params.indexing_policy.excluded_paths, [])) > 0 ? contains(container_params.indexing_policy.included_paths[*].path, "/*") || contains(container_params.indexing_policy.excluded_paths[*].path, "/*") : true ] ]) ) error_message = "Either 'included_paths' or 'excluded_paths' must contain the path '/*' if they are specified" } }