Skip to content

Commit

Permalink
feat: refactor naming convention and upgrade ux for schema_grants
Browse files Browse the repository at this point in the history
  • Loading branch information
PiotrSierkin-Ki committed Apr 17, 2024
1 parent e9d581c commit f426381
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 25 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ module "snowflake_database_role" {
| <a name="input_namespace"></a> [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 |
| <a name="input_parent_database_role"></a> [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 |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_schema_grants"></a> [schema\_grants](#input\_schema\_grants) | Grants on a schema level | <pre>list(object({<br> all_privileges = optional(bool)<br> with_grant_option = optional(bool, false)<br> privileges = optional(list(string), null)<br> all_schemas_in_database = optional(bool)<br> future_schemas_in_database = optional(bool)<br> schema_name = optional(string, null)<br> }))</pre> | `[]` | no |
| <a name="input_schema_grants"></a> [schema\_grants](#input\_schema\_grants) | Grants on a schema level | <pre>list(object({<br> all_privileges = optional(bool)<br> with_grant_option = optional(bool, false)<br> privileges = optional(list(string), null)<br> all_schemas_in_database = optional(bool, false)<br> future_schemas_in_database = optional(bool, false)<br> schema_name = optional(string, null)<br> }))</pre> | `[]` | no |
| <a name="input_schema_objects_grants"></a> [schema\_objects\_grants](#input\_schema\_objects\_grants) | Grants on a schema object level<br><br> Example usage:<br><br> schema\_objects\_grants = {<br> "TABLE" = [<br> {<br> privileges = ["SELECT"]<br> object\_name = "TEST\_TABLE"<br> schema\_name = "BRONZE"<br> },<br> {<br> all\_privileges = true<br> object\_name = "TEST\_TABLE\_2"<br> schema\_name = "BRONZE"<br> }<br> ]<br> "SECRET" = [<br> {<br> all\_privileges = true<br> object\_name = "SERVICE\_NOW\_CREDS\_PW"<br> schema\_name = "BRONZE"<br> }<br> ]<br> "ALERT" = [<br> {<br> all\_privileges = true<br> on\_future = true<br> on\_all = true<br> }<br> ]<br> }<br><br> Note: If you don't provide a schema\_name, the grants will be created in plural form.<br> 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) | <pre>map(list(object({<br> all_privileges = optional(bool)<br> with_grant_option = optional(bool)<br> privileges = optional(list(string))<br> object_name = optional(string)<br> on_all = optional(bool, false)<br> schema_name = optional(string)<br> on_future = optional(bool, false)<br> })))</pre> | `{}` | no |
| <a name="input_stage"></a> [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).<br>Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no |
Expand All @@ -115,6 +115,7 @@ module "snowflake_database_role" {
| Name | Description |
|------|-------------|
| <a name="output_name"></a> [name](#output\_name) | Name of the database role |
| <a name="output_name_fully_qualified"></a> [name\_fully\_qualified](#output\_name\_fully\_qualified) | Name of the database role in fully qualified format ("DB\_NAME"."ROLE\_NAME") |

## Providers

Expand Down
34 changes: 25 additions & 9 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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 : [
Expand Down Expand Up @@ -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
}
Expand Down
4 changes: 2 additions & 2 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
1 change: 0 additions & 1 deletion outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

14 changes: 2 additions & 12 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,15 @@ 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 = []
validation {
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" {
Expand Down

0 comments on commit f426381

Please sign in to comment.