From f426381c1070a17b34c0ff279233d2b5b66c6420 Mon Sep 17 00:00:00 2001 From: Piotr Sierkin Date: Wed, 17 Apr 2024 17:27:18 +0200 Subject: [PATCH] feat: refactor naming convention and upgrade ux for schema_grants --- README.md | 3 ++- locals.tf | 34 +++++++++++++++++++++++++--------- main.tf | 4 ++-- outputs.tf | 1 - variables.tf | 14 ++------------ 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 860e6c1..731968d 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ module "snowflake_database_role" { | [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 | | [parent\_database\_role](#input\_parent\_database\_role) | Fully qualified Parent Database Role name (`DB_NAME.ROLE_NAME`), to create parent-child relationship | `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 | -| [schema\_grants](#input\_schema\_grants) | Grants on a schema level |
list(object({
all_privileges = optional(bool)
with_grant_option = optional(bool, false)
privileges = optional(list(string), null)
all_schemas_in_database = optional(bool)
future_schemas_in_database = optional(bool)
schema_name = optional(string, null)
}))
| `[]` | no | +| [schema\_grants](#input\_schema\_grants) | Grants on a schema level |
list(object({
all_privileges = optional(bool)
with_grant_option = optional(bool, false)
privileges = optional(list(string), null)
all_schemas_in_database = optional(bool, false)
future_schemas_in_database = optional(bool, false)
schema_name = optional(string, null)
}))
| `[]` | no | | [schema\_objects\_grants](#input\_schema\_objects\_grants) | Grants on a schema object level

Example usage:

schema\_objects\_grants = {
"TABLE" = [
{
privileges = ["SELECT"]
object\_name = "TEST\_TABLE"
schema\_name = "BRONZE"
},
{
all\_privileges = true
object\_name = "TEST\_TABLE\_2"
schema\_name = "BRONZE"
}
]
"SECRET" = [
{
all\_privileges = true
object\_name = "SERVICE\_NOW\_CREDS\_PW"
schema\_name = "BRONZE"
}
]
"ALERT" = [
{
all\_privileges = true
on\_future = true
on\_all = true
}
]
}

Note: If you don't provide a schema\_name, the grants will be created in plural form.
List of the all objects can be found [here](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_privileges_to_role#object_type) |
map(list(object({
all_privileges = optional(bool)
with_grant_option = optional(bool)
privileges = optional(list(string))
object_name = optional(string)
on_all = optional(bool, false)
schema_name = optional(string)
on_future = optional(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 | | [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 | @@ -115,6 +115,7 @@ module "snowflake_database_role" { | Name | Description | |------|-------------| | [name](#output\_name) | Name of the database role | +| [name\_fully\_qualified](#output\_name\_fully\_qualified) | Name of the database role in fully qualified format ("DB\_NAME"."ROLE\_NAME") | ## Providers diff --git a/locals.tf b/locals.tf index e44da22..871d06a 100644 --- a/locals.tf +++ b/locals.tf @@ -9,18 +9,34 @@ locals { database_grants = { for database_grant in var.database_grants : - "${one(snowflake_database_role.this[*].database)}_${one(snowflake_database_role.this[*].name)}_${database_grant.all_privileges == true ? "ALL" : join("_", database_grant.privileges)}" => database_grant + "${one(snowflake_database_role.this[*].database)}_${one(snowflake_database_role.this[*].name)}_${database_grant.all_privileges == true ? "ALL" : "CUSTOM"}" => database_grant } schema_grants = { - for schema_grant in var.schema_grants : + for index, schema_grant in flatten([ + for grant in var.schema_grants : grant.future_schemas_in_database && grant.all_schemas_in_database ? [ + merge( + grant, + { + future_schemas_in_database = true, + all_schemas_in_database = false + } + ), + merge( + grant, + { + future_schemas_in_database = false, + all_schemas_in_database = true + } + ) + ] : [grant] + ]) : "${one(snowflake_database_role.this[*].database)}_${one(snowflake_database_role.this[*].name)}_${ schema_grant.schema_name != null ? schema_grant.schema_name : - schema_grant.all_schemas_in_database != null ? "ALL_SCHEMAS" : - schema_grant.future_schemas_in_database != null ? "FUTURE_SCHEMAS" : "" - }_${schema_grant.all_privileges == true ? "ALL" : join("_", schema_grant.privileges)}" => schema_grant + schema_grant.all_schemas_in_database != false ? "ALL_SCHEMAS" : + schema_grant.future_schemas_in_database != false ? "FUTURE_SCHEMAS" : "" + }_${schema_grant.all_privileges == true ? "ALL" : "CUSTOM"}_${index}" => schema_grant } - schema_objects_grants = { for index, grant in flatten([ for object_type, grants in var.schema_objects_grants : [ @@ -53,15 +69,15 @@ locals { ] ]) : "${one(snowflake_database_role.this[*].database)}_${one(snowflake_database_role.this[*].name)}${ grant.object_type != null && grant.object_name != null ? - "_${grant.object_type}_${grant.object_name}_${grant.all_privileges == true ? "ALL" : join("_", grant.privileges)}" + "_${grant.object_type}_${grant.object_name}_${grant.all_privileges == true ? "ALL" : "CUSTOM"}" : "" }${ grant.on_all != null && grant.on_all ? - "_ALL_${grant.object_type}${grant.schema_name != null ? "_${grant.schema_name}_${grant.all_privileges == true ? "ALL" : join("_", grant.privileges)}" : ""}" + "_ALL_${grant.object_type}${grant.schema_name != null ? "_${grant.schema_name}_${grant.all_privileges == true ? "ALL" : "CUSTOM"}" : ""}" : "" }${ grant.on_future != null && grant.on_future ? - "_FUTURE_${grant.object_type}${grant.schema_name != null ? "_${grant.schema_name}_${grant.all_privileges == true ? "ALL" : join("_", grant.privileges)}" : ""}" + "_FUTURE_${grant.object_type}${grant.schema_name != null ? "_${grant.schema_name}_${grant.all_privileges == true ? "ALL" : "CUSTOM"}" : ""}" : "" }" => grant } diff --git a/main.tf b/main.tf index ab0f429..c946856 100644 --- a/main.tf +++ b/main.tf @@ -50,9 +50,9 @@ resource "snowflake_grant_privileges_to_database_role" "schema_grants" { database_role_name = local.database_role_name on_schema { - all_schemas_in_database = each.value.all_schemas_in_database != null ? one(snowflake_database_role.this[*].database) : null + all_schemas_in_database = each.value.all_schemas_in_database != false ? one(snowflake_database_role.this[*].database) : null schema_name = each.value.schema_name != null ? "\"${one(snowflake_database_role.this[*].database)}\".\"${each.value.schema_name}\"" : null - future_schemas_in_database = each.value.future_schemas_in_database != null ? one(snowflake_database_role.this[*].database) : null + future_schemas_in_database = each.value.future_schemas_in_database != false ? one(snowflake_database_role.this[*].database) : null } } diff --git a/outputs.tf b/outputs.tf index b9e5d8f..f85fdbc 100644 --- a/outputs.tf +++ b/outputs.tf @@ -7,4 +7,3 @@ output "name_fully_qualified" { description = "Name of the database role in fully qualified format (\"DB_NAME\".\"ROLE_NAME\")" value = local.database_role_name } - diff --git a/variables.tf b/variables.tf index 9e8dd5f..8509a86 100644 --- a/variables.tf +++ b/variables.tf @@ -49,8 +49,8 @@ variable "schema_grants" { all_privileges = optional(bool) with_grant_option = optional(bool, false) privileges = optional(list(string), null) - all_schemas_in_database = optional(bool) - future_schemas_in_database = optional(bool) + all_schemas_in_database = optional(bool, false) + future_schemas_in_database = optional(bool, false) schema_name = optional(string, null) })) default = [] @@ -58,16 +58,6 @@ variable "schema_grants" { condition = alltrue([for grant in var.schema_grants : (grant.privileges != null) != (grant.all_privileges == true)]) error_message = "Variable `schema_grants` fails validation - only one of `privileges` or `all_privileges` can be set." } - validation { - condition = alltrue([for grant in var.schema_grants : - sum([ - grant.all_schemas_in_database != null ? 1 : 0, - grant.future_schemas_in_database != null ? 1 : 0, - grant.schema_name != null ? 1 : 0 - ]) == 1 - ]) - error_message = "Variable `schema_grants` fails validation - only one of `all_schemas_in_database`, `future_schemas_in_database`, or `schema_name` can be set." - } } variable "schema_objects_grants" {