From 6607804afaa64af4042f5745efbf1a43e924e90a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Gniewek-W=C4=99grzyn?= Date: Thu, 7 Nov 2024 16:28:11 +0100 Subject: [PATCH] feat: replace `context.tf` with context provider --- .pre-commit-config.yaml | 2 - .tflint.hcl | 3 - README.md | 37 ++-- context.tf | 279 ------------------------------ examples/complete/README.md | 33 +--- examples/complete/context.tf | 279 ------------------------------ examples/complete/fixtures.tfvars | 29 +--- examples/complete/main.tf | 32 +++- examples/complete/outputs.tf | 4 +- examples/complete/providers.tf | 11 ++ examples/complete/variables.tf | 4 + examples/complete/versions.tf | 9 +- examples/simple/README.md | 22 +-- examples/simple/context.tf | 279 ------------------------------ locals.tf | 112 ++++++------ main.tf | 77 +++++---- variables.tf | 86 ++++++--- versions.tf | 4 + 18 files changed, 241 insertions(+), 1061 deletions(-) delete mode 100644 .tflint.hcl delete mode 100644 context.tf delete mode 100644 examples/complete/context.tf create mode 100644 examples/complete/variables.tf delete mode 100644 examples/simple/context.tf diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a646d0b..fda80d2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,8 +5,6 @@ repos: - id: terraform-validate # It should be the first step as it runs terraform init required by tflint - id: terraform-fmt - id: tflint - args: - - "--config=__GIT_ROOT__/.tflint.hcl" - repo: https://github.com/terraform-docs/terraform-docs rev: "v0.18.0" # Get the latest from: https://github.com/terraform-docs/terraform-docs/releases diff --git a/.tflint.hcl b/.tflint.hcl deleted file mode 100644 index 3b6ace1..0000000 --- a/.tflint.hcl +++ /dev/null @@ -1,3 +0,0 @@ -rule "terraform_standard_module_structure" { - enabled = false # Fails on context.tf -} diff --git a/README.md b/README.md index 5f03182..17f67fd 100644 --- a/README.md +++ b/README.md @@ -70,45 +70,29 @@ For more information, refer to [variables.tf](variables.tf), list of inputs belo | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no | -| [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no | | [catalog](#input\_catalog) | Parameter that specifies the default catalog to use for Iceberg tables. | `string` | `null` | no | | [comment](#input\_comment) | Specifies a comment for the schema | `string` | `null` | no | -| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no | +| [context\_templates](#input\_context\_templates) | Map of context templates used for naming conventions - this variable supersedes `naming_scheme.properties` and `naming_scheme.delimiter` configuration | `map(string)` | `{}` | no | | [create\_default\_roles](#input\_create\_default\_roles) | Whether the default database roles should be created | `bool` | `false` | no | | [data\_retention\_time\_in\_days](#input\_data\_retention\_time\_in\_days) | Specifies the number of days for which Time Travel actions (CLONE and UNDROP) can be performed on the schema,
as well as specifying the default Time Travel retention time for all tables created in the schema | `number` | `1` | no | | [database](#input\_database) | Database where the schema should be created | `string` | n/a | yes | | [default\_ddl\_collation](#input\_default\_ddl\_collation) | Specifies a default collation specification for all schemas and tables added to the database.
It can be overridden on schema or table level. | `string` | `null` | no | -| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | -| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | -| [descriptor\_name](#input\_descriptor\_name) | Name of the descriptor used to form a resource name | `string` | `"snowflake-schema"` | no | | [enable\_console\_output](#input\_enable\_console\_output) | Enables console output for user tasks. | `bool` | `null` | no | -| [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | -| [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | | [external\_volume](#input\_external\_volume) | Parameter that specifies the default external volume to use for Iceberg tables. | `string` | `null` | no | -| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | | [is\_transient](#input\_is\_transient) | Specifies a schema as transient.
Transient schemas do not have a Fail-safe period so they do not incur additional storage costs once they leave Time Travel;
however, this means they are also not protected by Fail-safe in the event of a data loss. | `bool` | `false` | no | -| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no | -| [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | -| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | -| [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no | | [log\_level](#input\_log\_level) | Specifies the severity level of messages that should be ingested and made available in the active event table.
Valid options are: [TRACE DEBUG INFO WARN ERROR FATAL OFF].
Messages at the specified level (and at more severe levels) are ingested. | `string` | `null` | no | | [max\_data\_extension\_time\_in\_days](#input\_max\_data\_extension\_time\_in\_days) | Object parameter that specifies the maximum number of days for which Snowflake can extend the data retention period
for tables in the database to prevent streams on the tables from becoming stale. | `number` | `null` | no | -| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no | -| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no | +| [name](#input\_name) | Name of the resource | `string` | n/a | yes | +| [name\_scheme](#input\_name\_scheme) | Naming scheme configuration for the resource. This configuration is used to generate names using context provider:
- `properties` - list of properties to use when creating the name - is superseded by `var.context_templates`
- `delimiter` - delimited used to create the name from `properties` - is superseded by `var.context_templates`
- `context_template_name` - name of the context template used to create the name
- `replace_chars_regex` - regex to use for replacing characters in property-values created by the provider - any characters that match the regex will be removed from the name
- `extra_values` - map of extra label-value pairs, used to create a name |
object({
properties = optional(list(string), ["name"])
delimiter = optional(string, "_")
context_template_name = optional(string, "snowflake-schema")
replace_chars_regex = optional(string, "[^a-zA-Z0-9_]")
extra_values = optional(map(string))
})
| `{}` | no | | [pipe\_execution\_paused](#input\_pipe\_execution\_paused) | Pauses the execution of a pipe. | `bool` | `null` | no | | [quoted\_identifiers\_ignore\_case](#input\_quoted\_identifiers\_ignore\_case) | If true, the case of quoted identifiers is ignored. | `bool` | `null` | no | -| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | | [replace\_invalid\_characters](#input\_replace\_invalid\_characters) | Specifies whether to replace invalid UTF-8 characters with the Unicode replacement character () in query results for an Iceberg table.
You can only set this parameter for tables that use an external Iceberg catalog. | `bool` | `null` | no | -| [roles](#input\_roles) | Database roles created in the scheme scope |
map(object({
enabled = optional(bool, true)
descriptor_name = optional(string, "snowflake-database-role")
role_ownership_grant = optional(string)
granted_to_roles = optional(list(string))
granted_to_database_roles = optional(list(string))
granted_database_roles = optional(list(string))
schema_grants = optional(list(object({
all_privileges = optional(bool)
with_grant_option = optional(bool, false)
privileges = optional(list(string), null)
})))
schema_objects_grants = optional(map(list(object({
all_privileges = optional(bool)
with_grant_option = optional(bool)
privileges = optional(list(string), null)
object_name = optional(string)
on_all = optional(bool, false)
on_future = optional(bool, false)
}))), {})
}))
| `{}` | no | +| [roles](#input\_roles) | Database roles created in the scheme scope |
map(object({
name_scheme = optional(object({
properties = optional(list(string))
delimiter = optional(string)
context_template_name = optional(string)
replace_chars_regex = optional(string)
extra_labels = optional(map(string))
}))
role_ownership_grant = optional(string)
granted_to_roles = optional(list(string))
granted_to_database_roles = optional(list(string))
granted_database_roles = optional(list(string))
schema_grants = optional(list(object({
all_privileges = optional(bool)
with_grant_option = optional(bool, false)
privileges = optional(list(string), null)
})))
schema_objects_grants = optional(map(list(object({
all_privileges = optional(bool)
with_grant_option = optional(bool)
privileges = optional(list(string), null)
object_name = optional(string)
on_all = optional(bool, false)
on_future = optional(bool, false)
}))), {})
}))
| `{}` | no | | [skip\_schema\_creation](#input\_skip\_schema\_creation) | Should schema creation be skipped but allow all other resources to be created.
Useful if schema already exsists but you want to add e.g. access roles." | `bool` | `false` | no | -| [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | -| [stages](#input\_stages) | Stages to be created in the schema |
map(object({
enabled = optional(bool, true)
descriptor_name = optional(string, "snowflake-stage")
aws_external_id = optional(string)
comment = optional(string)
copy_options = optional(string)
credentials = optional(string)
directory = optional(string)
encryption = optional(string)
file_format = optional(string)
snowflake_iam_user = optional(string)
storage_integration = optional(string)
url = optional(string)
roles = optional(map(object({
descriptor_name = optional(string, "snowflake-database-role")
with_grant_option = optional(bool)
granted_to_roles = optional(list(string))
granted_to_database_roles = optional(list(string))
granted_database_roles = optional(list(string))
stage_grants = optional(list(string))
all_privileges = optional(bool)
})), ({}))
create_default_roles = optional(bool)
}))
| `{}` | no | +| [stages](#input\_stages) | Stages to be created in the schema |
map(object({
name_scheme = optional(object({
properties = optional(list(string))
delimiter = optional(string)
context_template_name = optional(string)
replace_chars_regex = optional(string)
extra_labels = optional(map(string))
}))
aws_external_id = optional(string)
comment = optional(string)
copy_options = optional(string)
credentials = optional(string)
directory = optional(string)
encryption = optional(string)
file_format = optional(string)
snowflake_iam_user = optional(string)
storage_integration = optional(string)
url = optional(string)
create_default_roles = optional(bool)
roles = optional(map(object({
name_scheme = optional(object({
properties = optional(list(string))
delimiter = optional(string)
context_template_name = optional(string)
replace_chars_regex = optional(string)
extra_labels = optional(map(string))
}))
with_grant_option = optional(bool)
granted_to_roles = optional(list(string))
granted_to_database_roles = optional(list(string))
granted_database_roles = optional(list(string))
stage_grants = optional(list(string))
all_privileges = optional(bool)
})), {})
}))
| `{}` | no | | [storage\_serialization\_policy](#input\_storage\_serialization\_policy) | The storage serialization policy for Iceberg tables that use Snowflake as the catalog.
Valid options are: [COMPATIBLE OPTIMIZED]. | `string` | `null` | no | | [suspend\_task\_after\_num\_failures](#input\_suspend\_task\_after\_num\_failures) | How many times a task must fail in a row before it is automatically suspended. 0 disables auto-suspending. | `number` | `null` | no | -| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no | | [task\_auto\_retry\_attempts](#input\_task\_auto\_retry\_attempts) | Maximum automatic retries allowed for a user task. | `number` | `null` | no | -| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no | | [trace\_level](#input\_trace\_level) | Controls how trace events are ingested into the event table.
Valid options are: [ALWAYS ON\_EVENT OFF]." | `string` | `null` | no | | [user\_task\_managed\_initial\_warehouse\_size](#input\_user\_task\_managed\_initial\_warehouse\_size) | The initial size of warehouse to use for managed warehouses in the absence of history. | `string` | `null` | no | | [user\_task\_minimum\_trigger\_interval\_in\_seconds](#input\_user\_task\_minimum\_trigger\_interval\_in\_seconds) | Minimum amount of time between Triggered Task executions in seconds. | `number` | `null` | no | @@ -120,11 +104,9 @@ For more information, refer to [variables.tf](variables.tf), list of inputs belo | Name | Source | Version | |------|--------|---------| | [roles\_deep\_merge](#module\_roles\_deep\_merge) | Invicton-Labs/deepmerge/null | 0.1.5 | -| [schema\_label](#module\_schema\_label) | cloudposse/label/null | 0.25.0 | -| [snowflake\_custom\_role](#module\_snowflake\_custom\_role) | getindata/database-role/snowflake | 1.1.1 | -| [snowflake\_default\_role](#module\_snowflake\_default\_role) | getindata/database-role/snowflake | 1.1.1 | -| [snowflake\_stage](#module\_snowflake\_stage) | getindata/stage/snowflake | 2.1.1 | -| [this](#module\_this) | cloudposse/label/null | 0.25.0 | +| [snowflake\_custom\_role](#module\_snowflake\_custom\_role) | getindata/database-role/snowflake | 2.0.1 | +| [snowflake\_default\_role](#module\_snowflake\_default\_role) | getindata/database-role/snowflake | 2.0.1 | +| [snowflake\_stage](#module\_snowflake\_stage) | getindata/stage/snowflake | 3.0.0 | ## Outputs @@ -160,6 +142,7 @@ For more information, refer to [variables.tf](variables.tf), list of inputs belo | Name | Version | |------|---------| +| [context](#provider\_context) | >=0.4.0 | | [snowflake](#provider\_snowflake) | ~> 0.94 | ## Requirements @@ -167,6 +150,7 @@ For more information, refer to [variables.tf](variables.tf), list of inputs belo | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.3 | +| [context](#requirement\_context) | >=0.4.0 | | [snowflake](#requirement\_snowflake) | ~> 0.94 | ## Resources @@ -174,6 +158,7 @@ For more information, refer to [variables.tf](variables.tf), list of inputs belo | Name | Type | |------|------| | [snowflake_schema.this](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/schema) | resource | +| [context_label.this](https://registry.terraform.io/providers/cloudposse/context/latest/docs/data-sources/label) | data source | ## CONTRIBUTING diff --git a/context.tf b/context.tf deleted file mode 100644 index 5e0ef88..0000000 --- a/context.tf +++ /dev/null @@ -1,279 +0,0 @@ -# -# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label -# All other instances of this file should be a copy of that one -# -# -# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf -# and then place it in your Terraform module to automatically get -# Cloud Posse's standard configuration inputs suitable for passing -# to Cloud Posse modules. -# -# curl -sL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf -o context.tf -# -# Modules should access the whole context as `module.this.context` -# to get the input variables with nulls for defaults, -# for example `context = module.this.context`, -# and access individual variables as `module.this.`, -# with final values filled in. -# -# For example, when using defaults, `module.this.context.delimiter` -# will be null, and `module.this.delimiter` will be `-` (hyphen). -# - -module "this" { - source = "cloudposse/label/null" - version = "0.25.0" # requires Terraform >= 0.13.0 - - enabled = var.enabled - namespace = var.namespace - tenant = var.tenant - environment = var.environment - stage = var.stage - name = var.name - delimiter = var.delimiter - attributes = var.attributes - tags = var.tags - additional_tag_map = var.additional_tag_map - label_order = var.label_order - regex_replace_chars = var.regex_replace_chars - id_length_limit = var.id_length_limit - label_key_case = var.label_key_case - label_value_case = var.label_value_case - descriptor_formats = var.descriptor_formats - labels_as_tags = var.labels_as_tags - - context = var.context -} - -# Copy contents of cloudposse/terraform-null-label/variables.tf here - -variable "context" { - type = any - default = { - enabled = true - namespace = null - tenant = null - environment = null - stage = null - name = null - delimiter = null - attributes = [] - tags = {} - additional_tag_map = {} - regex_replace_chars = null - label_order = [] - id_length_limit = null - label_key_case = null - label_value_case = null - descriptor_formats = {} - # Note: we have to use [] instead of null for unset lists due to - # https://github.com/hashicorp/terraform/issues/28137 - # which was not fixed until Terraform 1.0.0, - # but we want the default to be all the labels in `label_order` - # and we want users to be able to prevent all tag generation - # by setting `labels_as_tags` to `[]`, so we need - # a different sentinel to indicate "default" - labels_as_tags = ["unset"] - } - description = <<-EOT - Single object for setting entire context at once. - See description of individual variables for details. - Leave string and numeric variables as `null` to use default value. - Individual variable settings (non-null) override settings in context object, - except for attributes, tags, and additional_tag_map, which are merged. - EOT - - validation { - condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"]) - error_message = "Allowed values: `lower`, `title`, `upper`." - } - - validation { - condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"]) - error_message = "Allowed values: `lower`, `title`, `upper`, `none`." - } -} - -variable "enabled" { - type = bool - default = null - description = "Set to false to prevent the module from creating any resources" -} - -variable "namespace" { - type = string - default = null - description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" -} - -variable "tenant" { - type = string - default = null - description = "ID element _(Rarely used, not included by default)_. A customer identifier, indicating who this instance of a resource is for" -} - -variable "environment" { - type = string - default = null - description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" -} - -variable "stage" { - type = string - default = null - description = "ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release'" -} - -variable "name" { - type = string - default = null - description = <<-EOT - ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'. - This is the only ID element not also included as a `tag`. - The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. - EOT -} - -variable "delimiter" { - type = string - default = null - description = <<-EOT - Delimiter to be used between ID elements. - Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. - EOT -} - -variable "attributes" { - type = list(string) - default = [] - description = <<-EOT - ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`, - in the order they appear in the list. New attributes are appended to the - end of the list. The elements of the list are joined by the `delimiter` - and treated as a single ID element. - EOT -} - -variable "labels_as_tags" { - type = set(string) - default = ["default"] - description = <<-EOT - Set of labels (ID elements) to include as tags in the `tags` output. - Default is to include all labels. - Tags with empty values will not be included in the `tags` output. - Set to `[]` to suppress all generated tags. - **Notes:** - The value of the `name` tag, if included, will be the `id`, not the `name`. - Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be - changed in later chained modules. Attempts to change it will be silently ignored. - EOT -} - -variable "tags" { - type = map(string) - default = {} - description = <<-EOT - Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`). - Neither the tag keys nor the tag values will be modified by this module. - EOT -} - -variable "additional_tag_map" { - type = map(string) - default = {} - description = <<-EOT - Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`. - This is for some rare cases where resources want additional configuration of tags - and therefore take a list of maps with tag key, value, and additional configuration. - EOT -} - -variable "label_order" { - type = list(string) - default = null - description = <<-EOT - The order in which the labels (ID elements) appear in the `id`. - Defaults to ["namespace", "environment", "stage", "name", "attributes"]. - You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. - EOT -} - -variable "regex_replace_chars" { - type = string - default = null - description = <<-EOT - Terraform regular expression (regex) string. - Characters matching the regex will be removed from the ID elements. - If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. - EOT -} - -variable "id_length_limit" { - type = number - default = null - description = <<-EOT - Limit `id` to this many characters (minimum 6). - Set to `0` for unlimited length. - Set to `null` for keep the existing setting, which defaults to `0`. - Does not affect `id_full`. - EOT - validation { - condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0 - error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length." - } -} - -variable "label_key_case" { - type = string - default = null - description = <<-EOT - Controls the letter case of the `tags` keys (label names) for tags generated by this module. - Does not affect keys of tags passed in via the `tags` input. - Possible values: `lower`, `title`, `upper`. - Default value: `title`. - EOT - - validation { - condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case) - error_message = "Allowed values: `lower`, `title`, `upper`." - } -} - -variable "label_value_case" { - type = string - default = null - description = <<-EOT - Controls the letter case of ID elements (labels) as included in `id`, - set as tag values, and output by this module individually. - Does not affect values of tags passed in via the `tags` input. - Possible values: `lower`, `title`, `upper` and `none` (no transformation). - Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs. - Default value: `lower`. - EOT - - validation { - condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case) - error_message = "Allowed values: `lower`, `title`, `upper`, `none`." - } -} - -variable "descriptor_formats" { - type = any - default = {} - description = <<-EOT - Describe additional descriptors to be output in the `descriptors` output map. - Map of maps. Keys are names of descriptors. Values are maps of the form - `{ - format = string - labels = list(string) - }` - (Type is `any` so the map values can later be enhanced to provide additional options.) - `format` is a Terraform format string to be passed to the `format()` function. - `labels` is a list of labels, in order, to pass to `format()` function. - Label values will be normalized before being passed to `format()` so they will be - identical to how they appear in `id`. - Default is `{}` (`descriptors` output will be empty). - EOT -} - -#### End of copy of cloudposse/terraform-null-label/variables.tf diff --git a/examples/complete/README.md b/examples/complete/README.md index d2e96ae..7b51b25 100644 --- a/examples/complete/README.md +++ b/examples/complete/README.md @@ -35,50 +35,34 @@ terraform destroy -var-file=fixtures.tfvars | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no | -| [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no | -| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no | -| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | -| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | -| [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | -| [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | -| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | -| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no | -| [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | -| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | -| [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no | -| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no | -| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no | -| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | -| [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | -| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no | -| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no | +| [context\_templates](#input\_context\_templates) | A map of context templates used to generate names | `map(string)` | n/a | yes | ## Modules | Name | Source | Version | |------|--------|---------| -| [this](#module\_this) | cloudposse/label/null | 0.25.0 | -| [this\_schema](#module\_this\_schema) | ../../ | n/a | +| [existing\_schema](#module\_existing\_schema) | ../../ | n/a | +| [new\_schema](#module\_new\_schema) | ../../ | n/a | ## Outputs | Name | Description | |------|-------------| -| [schema](#output\_schema) | Schema module outputs | +| [new\_schema](#output\_new\_schema) | Schema module outputs | ## Providers | Name | Version | |------|---------| -| [snowflake](#provider\_snowflake) | ~> 0.94 | +| [snowflake](#provider\_snowflake) | >= 0.95 | ## Requirements | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.3 | -| [snowflake](#requirement\_snowflake) | ~> 0.94 | +| [terraform](#requirement\_terraform) | >= 1.5 | +| [context](#requirement\_context) | >=0.4.0 | +| [snowflake](#requirement\_snowflake) | >= 0.95 | ## Resources @@ -89,6 +73,7 @@ terraform destroy -var-file=fixtures.tfvars | [snowflake_database_role.db_role_1](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/database_role) | resource | | [snowflake_database_role.db_role_2](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/database_role) | resource | | [snowflake_database_role.db_role_3](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/database_role) | resource | +| [snowflake_schema.this](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/schema) | resource | | [snowflake_table.table_1](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/table) | resource | | [snowflake_table.table_2](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/table) | resource | diff --git a/examples/complete/context.tf b/examples/complete/context.tf deleted file mode 100644 index 5e0ef88..0000000 --- a/examples/complete/context.tf +++ /dev/null @@ -1,279 +0,0 @@ -# -# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label -# All other instances of this file should be a copy of that one -# -# -# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf -# and then place it in your Terraform module to automatically get -# Cloud Posse's standard configuration inputs suitable for passing -# to Cloud Posse modules. -# -# curl -sL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf -o context.tf -# -# Modules should access the whole context as `module.this.context` -# to get the input variables with nulls for defaults, -# for example `context = module.this.context`, -# and access individual variables as `module.this.`, -# with final values filled in. -# -# For example, when using defaults, `module.this.context.delimiter` -# will be null, and `module.this.delimiter` will be `-` (hyphen). -# - -module "this" { - source = "cloudposse/label/null" - version = "0.25.0" # requires Terraform >= 0.13.0 - - enabled = var.enabled - namespace = var.namespace - tenant = var.tenant - environment = var.environment - stage = var.stage - name = var.name - delimiter = var.delimiter - attributes = var.attributes - tags = var.tags - additional_tag_map = var.additional_tag_map - label_order = var.label_order - regex_replace_chars = var.regex_replace_chars - id_length_limit = var.id_length_limit - label_key_case = var.label_key_case - label_value_case = var.label_value_case - descriptor_formats = var.descriptor_formats - labels_as_tags = var.labels_as_tags - - context = var.context -} - -# Copy contents of cloudposse/terraform-null-label/variables.tf here - -variable "context" { - type = any - default = { - enabled = true - namespace = null - tenant = null - environment = null - stage = null - name = null - delimiter = null - attributes = [] - tags = {} - additional_tag_map = {} - regex_replace_chars = null - label_order = [] - id_length_limit = null - label_key_case = null - label_value_case = null - descriptor_formats = {} - # Note: we have to use [] instead of null for unset lists due to - # https://github.com/hashicorp/terraform/issues/28137 - # which was not fixed until Terraform 1.0.0, - # but we want the default to be all the labels in `label_order` - # and we want users to be able to prevent all tag generation - # by setting `labels_as_tags` to `[]`, so we need - # a different sentinel to indicate "default" - labels_as_tags = ["unset"] - } - description = <<-EOT - Single object for setting entire context at once. - See description of individual variables for details. - Leave string and numeric variables as `null` to use default value. - Individual variable settings (non-null) override settings in context object, - except for attributes, tags, and additional_tag_map, which are merged. - EOT - - validation { - condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"]) - error_message = "Allowed values: `lower`, `title`, `upper`." - } - - validation { - condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"]) - error_message = "Allowed values: `lower`, `title`, `upper`, `none`." - } -} - -variable "enabled" { - type = bool - default = null - description = "Set to false to prevent the module from creating any resources" -} - -variable "namespace" { - type = string - default = null - description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" -} - -variable "tenant" { - type = string - default = null - description = "ID element _(Rarely used, not included by default)_. A customer identifier, indicating who this instance of a resource is for" -} - -variable "environment" { - type = string - default = null - description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" -} - -variable "stage" { - type = string - default = null - description = "ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release'" -} - -variable "name" { - type = string - default = null - description = <<-EOT - ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'. - This is the only ID element not also included as a `tag`. - The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. - EOT -} - -variable "delimiter" { - type = string - default = null - description = <<-EOT - Delimiter to be used between ID elements. - Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. - EOT -} - -variable "attributes" { - type = list(string) - default = [] - description = <<-EOT - ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`, - in the order they appear in the list. New attributes are appended to the - end of the list. The elements of the list are joined by the `delimiter` - and treated as a single ID element. - EOT -} - -variable "labels_as_tags" { - type = set(string) - default = ["default"] - description = <<-EOT - Set of labels (ID elements) to include as tags in the `tags` output. - Default is to include all labels. - Tags with empty values will not be included in the `tags` output. - Set to `[]` to suppress all generated tags. - **Notes:** - The value of the `name` tag, if included, will be the `id`, not the `name`. - Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be - changed in later chained modules. Attempts to change it will be silently ignored. - EOT -} - -variable "tags" { - type = map(string) - default = {} - description = <<-EOT - Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`). - Neither the tag keys nor the tag values will be modified by this module. - EOT -} - -variable "additional_tag_map" { - type = map(string) - default = {} - description = <<-EOT - Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`. - This is for some rare cases where resources want additional configuration of tags - and therefore take a list of maps with tag key, value, and additional configuration. - EOT -} - -variable "label_order" { - type = list(string) - default = null - description = <<-EOT - The order in which the labels (ID elements) appear in the `id`. - Defaults to ["namespace", "environment", "stage", "name", "attributes"]. - You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. - EOT -} - -variable "regex_replace_chars" { - type = string - default = null - description = <<-EOT - Terraform regular expression (regex) string. - Characters matching the regex will be removed from the ID elements. - If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. - EOT -} - -variable "id_length_limit" { - type = number - default = null - description = <<-EOT - Limit `id` to this many characters (minimum 6). - Set to `0` for unlimited length. - Set to `null` for keep the existing setting, which defaults to `0`. - Does not affect `id_full`. - EOT - validation { - condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0 - error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length." - } -} - -variable "label_key_case" { - type = string - default = null - description = <<-EOT - Controls the letter case of the `tags` keys (label names) for tags generated by this module. - Does not affect keys of tags passed in via the `tags` input. - Possible values: `lower`, `title`, `upper`. - Default value: `title`. - EOT - - validation { - condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case) - error_message = "Allowed values: `lower`, `title`, `upper`." - } -} - -variable "label_value_case" { - type = string - default = null - description = <<-EOT - Controls the letter case of ID elements (labels) as included in `id`, - set as tag values, and output by this module individually. - Does not affect values of tags passed in via the `tags` input. - Possible values: `lower`, `title`, `upper` and `none` (no transformation). - Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs. - Default value: `lower`. - EOT - - validation { - condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case) - error_message = "Allowed values: `lower`, `title`, `upper`, `none`." - } -} - -variable "descriptor_formats" { - type = any - default = {} - description = <<-EOT - Describe additional descriptors to be output in the `descriptors` output map. - Map of maps. Keys are names of descriptors. Values are maps of the form - `{ - format = string - labels = list(string) - }` - (Type is `any` so the map values can later be enhanced to provide additional options.) - `format` is a Terraform format string to be passed to the `format()` function. - `labels` is a list of labels, in order, to pass to `format()` function. - Label values will be normalized before being passed to `format()` so they will be - identical to how they appear in `id`. - Default is `{}` (`descriptors` output will be empty). - EOT -} - -#### End of copy of cloudposse/terraform-null-label/variables.tf diff --git a/examples/complete/fixtures.tfvars b/examples/complete/fixtures.tfvars index 37d8286..d850e18 100644 --- a/examples/complete/fixtures.tfvars +++ b/examples/complete/fixtures.tfvars @@ -1,25 +1,6 @@ -namespace = "gid" -stage = "example" - -descriptor_formats = { - snowflake-database-role = { - labels = ["attributes", "name"] - format = "%v_%v" - } - snowflake-schema = { - labels = ["name", "attributes"] - format = "%v_%v" - } - snowflake-resource-monitor = { - labels = ["name", "attributes"] - format = "%v_%v" - } - snowflake-stage = { - labels = ["name", "attributes"] - format = "%v_%v" - } -} - -tags = { - Terraform = "True" +context_templates = { + snowflake-stage = "{{.name}}" + snowflake-schema = "{{.name}}" + snowflake-schema-database-role = "{{.schema}}_{{.name}}" + snowflake-project-schema = "{{.project}}_{{.name}}" } diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 9647694..c1b5429 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -21,9 +21,14 @@ resource "snowflake_database" "this" { name = "ANALYTICS_DB" } +resource "snowflake_schema" "this" { + name = "existing" + database = snowflake_database.this.name +} + resource "snowflake_table" "table_1" { database = snowflake_database.this.name - schema = module.this_schema.name + schema = module.new_schema.name name = "TEST_TABLE_1" column { @@ -40,7 +45,7 @@ resource "snowflake_table" "table_1" { resource "snowflake_table" "table_2" { database = snowflake_database.this.name - schema = module.this_schema.name + schema = module.new_schema.name name = "TEST_TABLE_2" column { @@ -55,11 +60,23 @@ resource "snowflake_table" "table_2" { } } -module "this_schema" { - source = "../../" - context = module.this.context +module "existing_schema" { + source = "../../" + context_templates = var.context_templates - name = "RAW" + name = snowflake_schema.this.name + database = snowflake_database.this.name + + skip_schema_creation = true + create_default_roles = true + +} + +module "new_schema" { + source = "../../" + context_templates = var.context_templates + + name = "raw" database = snowflake_database.this.name with_managed_access = false @@ -69,9 +86,6 @@ module "this_schema" { create_default_roles = true roles = { - readwrite = { # Disables the default readwrite role - enabled = false - } transformer = { # Modifies the default transformer role granted_to_roles = [snowflake_account_role.role_1.name] schema_objects_grants = { diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 6ff5738..a2b199c 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -1,4 +1,4 @@ -output "schema" { +output "new_schema" { description = "Schema module outputs" - value = module.this_schema + value = module.new_schema } diff --git a/examples/complete/providers.tf b/examples/complete/providers.tf index d343f0d..5b943b9 100644 --- a/examples/complete/providers.tf +++ b/examples/complete/providers.tf @@ -1 +1,12 @@ provider "snowflake" {} + +provider "context" { + properties = { + "environment" = {} + "name" = { required = true } + } + + values = { + environment = "dev" + } +} diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf new file mode 100644 index 0000000..f09a47d --- /dev/null +++ b/examples/complete/variables.tf @@ -0,0 +1,4 @@ +variable "context_templates" { + description = "A map of context templates used to generate names" + type = map(string) +} diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf index 28b216f..0c16dd3 100644 --- a/examples/complete/versions.tf +++ b/examples/complete/versions.tf @@ -1,10 +1,13 @@ terraform { - required_version = ">= 1.3" - + required_version = ">= 1.5" required_providers { snowflake = { source = "Snowflake-Labs/snowflake" - version = "~> 0.94" + version = ">= 0.95" + } + context = { + source = "cloudposse/context" + version = ">=0.4.0" } } } diff --git a/examples/simple/README.md b/examples/simple/README.md index 6287234..83579ed 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -32,32 +32,12 @@ terraform destroy ## Inputs -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no | -| [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no | -| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no | -| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | -| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | -| [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | -| [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | -| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | -| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no | -| [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | -| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | -| [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no | -| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no | -| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no | -| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | -| [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | -| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no | -| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no | +No inputs. ## Modules | Name | Source | Version | |------|--------|---------| -| [this](#module\_this) | cloudposse/label/null | 0.25.0 | | [this\_schema](#module\_this\_schema) | ../../ | n/a | ## Outputs diff --git a/examples/simple/context.tf b/examples/simple/context.tf deleted file mode 100644 index 5e0ef88..0000000 --- a/examples/simple/context.tf +++ /dev/null @@ -1,279 +0,0 @@ -# -# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label -# All other instances of this file should be a copy of that one -# -# -# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf -# and then place it in your Terraform module to automatically get -# Cloud Posse's standard configuration inputs suitable for passing -# to Cloud Posse modules. -# -# curl -sL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf -o context.tf -# -# Modules should access the whole context as `module.this.context` -# to get the input variables with nulls for defaults, -# for example `context = module.this.context`, -# and access individual variables as `module.this.`, -# with final values filled in. -# -# For example, when using defaults, `module.this.context.delimiter` -# will be null, and `module.this.delimiter` will be `-` (hyphen). -# - -module "this" { - source = "cloudposse/label/null" - version = "0.25.0" # requires Terraform >= 0.13.0 - - enabled = var.enabled - namespace = var.namespace - tenant = var.tenant - environment = var.environment - stage = var.stage - name = var.name - delimiter = var.delimiter - attributes = var.attributes - tags = var.tags - additional_tag_map = var.additional_tag_map - label_order = var.label_order - regex_replace_chars = var.regex_replace_chars - id_length_limit = var.id_length_limit - label_key_case = var.label_key_case - label_value_case = var.label_value_case - descriptor_formats = var.descriptor_formats - labels_as_tags = var.labels_as_tags - - context = var.context -} - -# Copy contents of cloudposse/terraform-null-label/variables.tf here - -variable "context" { - type = any - default = { - enabled = true - namespace = null - tenant = null - environment = null - stage = null - name = null - delimiter = null - attributes = [] - tags = {} - additional_tag_map = {} - regex_replace_chars = null - label_order = [] - id_length_limit = null - label_key_case = null - label_value_case = null - descriptor_formats = {} - # Note: we have to use [] instead of null for unset lists due to - # https://github.com/hashicorp/terraform/issues/28137 - # which was not fixed until Terraform 1.0.0, - # but we want the default to be all the labels in `label_order` - # and we want users to be able to prevent all tag generation - # by setting `labels_as_tags` to `[]`, so we need - # a different sentinel to indicate "default" - labels_as_tags = ["unset"] - } - description = <<-EOT - Single object for setting entire context at once. - See description of individual variables for details. - Leave string and numeric variables as `null` to use default value. - Individual variable settings (non-null) override settings in context object, - except for attributes, tags, and additional_tag_map, which are merged. - EOT - - validation { - condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"]) - error_message = "Allowed values: `lower`, `title`, `upper`." - } - - validation { - condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"]) - error_message = "Allowed values: `lower`, `title`, `upper`, `none`." - } -} - -variable "enabled" { - type = bool - default = null - description = "Set to false to prevent the module from creating any resources" -} - -variable "namespace" { - type = string - default = null - description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" -} - -variable "tenant" { - type = string - default = null - description = "ID element _(Rarely used, not included by default)_. A customer identifier, indicating who this instance of a resource is for" -} - -variable "environment" { - type = string - default = null - description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" -} - -variable "stage" { - type = string - default = null - description = "ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release'" -} - -variable "name" { - type = string - default = null - description = <<-EOT - ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'. - This is the only ID element not also included as a `tag`. - The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. - EOT -} - -variable "delimiter" { - type = string - default = null - description = <<-EOT - Delimiter to be used between ID elements. - Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. - EOT -} - -variable "attributes" { - type = list(string) - default = [] - description = <<-EOT - ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`, - in the order they appear in the list. New attributes are appended to the - end of the list. The elements of the list are joined by the `delimiter` - and treated as a single ID element. - EOT -} - -variable "labels_as_tags" { - type = set(string) - default = ["default"] - description = <<-EOT - Set of labels (ID elements) to include as tags in the `tags` output. - Default is to include all labels. - Tags with empty values will not be included in the `tags` output. - Set to `[]` to suppress all generated tags. - **Notes:** - The value of the `name` tag, if included, will be the `id`, not the `name`. - Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be - changed in later chained modules. Attempts to change it will be silently ignored. - EOT -} - -variable "tags" { - type = map(string) - default = {} - description = <<-EOT - Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`). - Neither the tag keys nor the tag values will be modified by this module. - EOT -} - -variable "additional_tag_map" { - type = map(string) - default = {} - description = <<-EOT - Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`. - This is for some rare cases where resources want additional configuration of tags - and therefore take a list of maps with tag key, value, and additional configuration. - EOT -} - -variable "label_order" { - type = list(string) - default = null - description = <<-EOT - The order in which the labels (ID elements) appear in the `id`. - Defaults to ["namespace", "environment", "stage", "name", "attributes"]. - You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. - EOT -} - -variable "regex_replace_chars" { - type = string - default = null - description = <<-EOT - Terraform regular expression (regex) string. - Characters matching the regex will be removed from the ID elements. - If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. - EOT -} - -variable "id_length_limit" { - type = number - default = null - description = <<-EOT - Limit `id` to this many characters (minimum 6). - Set to `0` for unlimited length. - Set to `null` for keep the existing setting, which defaults to `0`. - Does not affect `id_full`. - EOT - validation { - condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0 - error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length." - } -} - -variable "label_key_case" { - type = string - default = null - description = <<-EOT - Controls the letter case of the `tags` keys (label names) for tags generated by this module. - Does not affect keys of tags passed in via the `tags` input. - Possible values: `lower`, `title`, `upper`. - Default value: `title`. - EOT - - validation { - condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case) - error_message = "Allowed values: `lower`, `title`, `upper`." - } -} - -variable "label_value_case" { - type = string - default = null - description = <<-EOT - Controls the letter case of ID elements (labels) as included in `id`, - set as tag values, and output by this module individually. - Does not affect values of tags passed in via the `tags` input. - Possible values: `lower`, `title`, `upper` and `none` (no transformation). - Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs. - Default value: `lower`. - EOT - - validation { - condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case) - error_message = "Allowed values: `lower`, `title`, `upper`, `none`." - } -} - -variable "descriptor_formats" { - type = any - default = {} - description = <<-EOT - Describe additional descriptors to be output in the `descriptors` output map. - Map of maps. Keys are names of descriptors. Values are maps of the form - `{ - format = string - labels = list(string) - }` - (Type is `any` so the map values can later be enhanced to provide additional options.) - `format` is a Terraform format string to be passed to the `format()` function. - `labels` is a list of labels, in order, to pass to `format()` function. - Label values will be normalized before being passed to `format()` so they will be - identical to how they appear in `id`. - Default is `{}` (`descriptors` output will be empty). - EOT -} - -#### End of copy of cloudposse/terraform-null-label/variables.tf diff --git a/locals.tf b/locals.tf index 032df8e..18eb6cb 100644 --- a/locals.tf +++ b/locals.tf @@ -1,14 +1,16 @@ locals { - # Get a name from the descriptor. If not available, use default naming convention. - # Trim and replace function are used to avoid bare delimiters on both ends of the name and situation of adjacent delimiters. - name_from_descriptor = module.schema_label.enabled ? trim(replace( - lookup(module.schema_label.descriptors, var.descriptor_name, module.schema_label.id), "/${module.schema_label.delimiter}${module.schema_label.delimiter}+/", module.schema_label.delimiter - ), module.schema_label.delimiter) : null + context_template = lookup(var.context_templates, var.name_scheme.context_template_name, null) - create_default_roles = module.this.enabled && var.create_default_roles + default_role_naming_scheme = { + properties = ["schema", "name"] + context_template_name = "snowflake-schema-database-role" + extra_values = { + database = var.database + schema = var.name + } + } - schema = module.this.enabled ? coalesce(one(snowflake_schema.this[*].name), var.name) : null - database = var.database + schema = coalesce(one(snowflake_schema.this[*].name), var.name) # This needs to be the same as an object in roles variable role_template = { @@ -38,59 +40,59 @@ locals { readonly = { schema_grants = [{ privileges = ["USAGE"] - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] schema_objects_grants = { "TABLE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT"] on_all = true on_future = true }] "DYNAMIC TABLE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT"] on_all = true on_future = true }] "EXTERNAL TABLE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "REFERENCES"] on_all = true on_future = true }] "VIEW" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "REFERENCES"] on_all = true on_future = true }] "MATERIALIZED VIEW" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "REFERENCES"] on_all = true on_future = true }] "FILE FORMAT" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE"] on_all = true on_future = true }] "FUNCTION" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE"] on_all = true on_future = true }] "STAGE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE"] on_all = true on_future = true }] "TASK" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["MONITOR"] on_all = true on_future = true @@ -100,65 +102,65 @@ locals { readwrite = { schema_grants = [{ privileges = ["USAGE"] - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] schema_objects_grants = { "TABLE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "REBUILD"] on_all = true on_future = true }] "DYNAMIC TABLE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT"] on_all = true on_future = true }] "EXTERNAL TABLE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "REFERENCES"] on_all = true on_future = true }] "VIEW" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "REFERENCES"] on_all = true on_future = true }] "MATERIALIZED VIEW" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "REFERENCES"] on_all = true on_future = true }] "FILE FORMAT" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE"] on_all = true on_future = true }] "FUNCTION" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE"] on_all = true on_future = true }] "STAGE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE", "READ", "WRITE"] on_all = true on_future = true }] "TASK" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["MONITOR", "OPERATE"] on_all = true on_future = true }] "PROCEDURE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE"] on_all = true on_future = true @@ -168,74 +170,74 @@ locals { admin = { schema_grants = [{ privileges = ["ALL PRIVILEGES"] - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] schema_objects_grants = { "TABLE" = [{ privileges = ["ALL PRIVILEGES"] on_all = true on_future = true - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] "DYNAMIC TABLE" = [{ privileges = ["ALL PRIVILEGES"] on_all = true on_future = true - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] "EXTERNAL TABLE" = [{ privileges = ["ALL PRIVILEGES"] on_all = true on_future = true - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] "VIEW" = [{ privileges = ["ALL PRIVILEGES"] on_all = true on_future = true - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] "MATERIALIZED VIEW" = [{ privileges = ["ALL PRIVILEGES"] on_all = true on_future = true - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] "FILE FORMAT" = [{ privileges = ["ALL PRIVILEGES"] on_all = true on_future = true - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] "FUNCTION" = [{ privileges = ["ALL PRIVILEGES"] on_all = true on_future = true - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] "STAGE" = [{ privileges = ["ALL PRIVILEGES"] on_all = true on_future = true - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] "TASK" = [{ privileges = ["ALL PRIVILEGES"] on_all = true on_future = true - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] "PROCEDURE" = [{ privileges = ["ALL PRIVILEGES"] on_all = true on_future = true - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered }] } } transformer = { schema_grants = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = [ "CREATE TEMPORARY TABLE", "CREATE TAG", @@ -256,61 +258,61 @@ locals { }] schema_objects_grants = { "TABLE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "REBUILD"] on_all = true on_future = true }] "DYNAMIC TABLE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["ALL PRIVILEGES"] on_all = true on_future = true }] "EXTERNAL TABLE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "REFERENCES"] on_all = true on_future = true }] "VIEW" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "REFERENCES"] on_all = true on_future = true }] "MATERIALIZED VIEW" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["SELECT", "REFERENCES"] on_all = true on_future = true }] "FILE FORMAT" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE"] on_all = true on_future = true }] "FUNCTION" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE"] on_all = true on_future = true }] "STAGE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE", "READ", "WRITE"] on_all = true on_future = true }] "TASK" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["MONITOR", "OPERATE"] on_all = true on_future = true }] "PROCEDURE" = [{ - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered privileges = ["USAGE"] on_all = true on_future = true @@ -328,7 +330,7 @@ locals { }, { for k, v in role : k => [ - for object in v : merge(object, { schema_name = local.name_from_descriptor }) + for object in v : merge(object, { schema_name = data.context_label.this.rendered }) ] if v != null && k == "schema_grants" }, @@ -338,7 +340,7 @@ locals { for grant in config : merge( grant, { - schema_name = local.name_from_descriptor + schema_name = data.context_label.this.rendered } ) ] @@ -357,7 +359,7 @@ locals { default_roles = { for role_name, role in local.roles_definition : role_name => role - if contains(keys(local.default_roles_definition), role_name) + if contains(keys(local.default_roles_definition), role_name) && var.create_default_roles } custom_roles = { @@ -370,7 +372,7 @@ locals { module.snowflake_default_role, module.snowflake_custom_role ) : role_name => role - if role.name != null + if role_name != null } } diff --git a/main.tf b/main.tf index 2b4b0cf..9c97c4d 100644 --- a/main.tf +++ b/main.tf @@ -1,20 +1,23 @@ -module "schema_label" { - source = "cloudposse/label/null" - version = "0.25.0" - context = module.this.context - - delimiter = coalesce(module.this.context.delimiter, "_") - regex_replace_chars = coalesce(module.this.context.regex_replace_chars, "/[^_a-zA-Z0-9]/") - label_value_case = coalesce(module.this.context.label_value_case, "upper") +data "context_label" "this" { + delimiter = local.context_template == null ? var.name_scheme.delimiter : null + properties = local.context_template == null ? var.name_scheme.properties : null + template = local.context_template + + replace_chars_regex = var.name_scheme.replace_chars_regex + + values = merge( + var.name_scheme.extra_values, + { name = var.name } + ) } resource "snowflake_schema" "this" { - count = module.this.enabled && !var.skip_schema_creation ? 1 : 0 + count = var.skip_schema_creation ? 0 : 1 - name = local.name_from_descriptor + name = data.context_label.this.rendered comment = var.comment - database = local.database + database = var.database is_transient = var.is_transient data_retention_time_in_days = var.data_retention_time_in_days @@ -41,15 +44,21 @@ module "snowflake_stage" { for_each = var.stages source = "getindata/stage/snowflake" - version = "2.1.1" - enabled = module.this.enabled && each.value.enabled - context = module.this.context + version = "3.0.0" + + context_templates = var.context_templates - name = each.key - descriptor_name = each.value.descriptor_name + name = each.key + name_scheme = merge({ + extra_values = { + database = var.database + schema = var.name + } }, + lookup(each.value, "name_scheme", {}) + ) schema = local.schema - database = local.database + database = var.database aws_external_id = each.value.aws_external_id comment = each.value.comment @@ -70,14 +79,16 @@ module "snowflake_default_role" { for_each = local.default_roles source = "getindata/database-role/snowflake" - version = "1.1.1" - context = module.this.context - enabled = local.create_default_roles && lookup(each.value, "enabled", true) + version = "2.0.1" - database_name = one(snowflake_schema.this[*].database) - name = each.key - attributes = [local.schema] - descriptor_name = lookup(each.value, "descriptor_name", "snowflake-database-role") + database_name = var.database + context_templates = var.context_templates + + name = each.key + name_scheme = merge( + local.default_role_naming_scheme, + lookup(each.value, "name_scheme", {}) + ) granted_to_roles = lookup(each.value, "granted_to_roles", []) granted_to_database_roles = lookup(each.value, "granted_to_database_roles", []) @@ -90,14 +101,16 @@ module "snowflake_custom_role" { for_each = local.custom_roles source = "getindata/database-role/snowflake" - version = "1.1.1" - context = module.this.context - enabled = module.this.enabled && lookup(each.value, "enabled", true) - - database_name = one(snowflake_schema.this[*].database) - name = each.key - attributes = [local.schema] - descriptor_name = lookup(each.value, "descriptor_name", "snowflake-database-role") + version = "2.0.1" + + database_name = var.database + context_templates = var.context_templates + + name = each.key + name_scheme = merge( + local.default_role_naming_scheme, + lookup(each.value, "name_scheme", {}) + ) granted_to_roles = lookup(each.value, "granted_to_roles", []) granted_to_database_roles = lookup(each.value, "granted_to_database_roles", []) diff --git a/variables.tf b/variables.tf index fb90f64..e2ac4f9 100644 --- a/variables.tf +++ b/variables.tf @@ -1,3 +1,8 @@ +variable "name" { + description = "Name of the resource" + type = string +} + variable "skip_schema_creation" { description = <