From 80e5dcc280c1069b15fb513b24c0b35d24f88c1a Mon Sep 17 00:00:00 2001 From: Daniel Noworyta Date: Wed, 24 Jul 2024 16:21:00 +0200 Subject: [PATCH] chore: added enabled flag (bool) to database role creation --- README.md | 18 +++++++++--------- examples/complete/main.tf | 15 +++++++++------ locals.tf | 10 ++++++---- outputs.tf | 2 +- variables.tf | 3 ++- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index c0bc1a1..71e6621 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,11 @@ Terraform module for Snowflake stage management. * Creates Snowflake stage -* Can create custom Snowflake databse-roles with role-to-role assignments +* Can create custom Snowflake database-roles with role-to-role assignments * Can create a set of default roles to simplify access management: * `READONLY` - granted `USAGE` or `READ` privilages - * `READWRITE` - granted `WRITE` privilages - * `ADMIN` - granted `READ`, `WRITE` privilages (role can be additionally granted with `OWNER` attribute when specified) + * `READWRITE` - granted `WRITE` privileges + * `ADMIN` - granted `READ`, `WRITE` privileges (role can be additionally granted with `OWNER` attribute when specified) ## USAGE @@ -35,7 +35,7 @@ module "snowflake_stage" { url = "s3://com.example.bucket/prefix" credentials = "AWS_KEY_ID='${var.example_aws_key_id}' AWS_SECRET_KEY='${var.example_aws_secret_key}'" - create_default_roles = true + create_default_database_roles = true } ``` @@ -48,11 +48,11 @@ module "snowflake_stage" { ## Breaking changes in v2.x of the module Due to breaking changes in Snowflake provider and additional code optimizations, **breaking changes** were introduced in `v2.0.0` version of this module. -Lst of code and variable (API) changes: +List of code and variable (API) changes: - Switched to `snowflake_grant_ownership` resource instead of provider-removed `snowflake_role_ownership_grant` - Switched to `snowflake_database_role` module to leverage new `database_roles` mechanism - `default_roles` and `custom_roles` are now combined and managed by single module -- `create_default_roles` variable was renamed to `create_default_databse_roles` +- `create_default_roles` variable was renamed to `create_default_database_roles` - `roles` variable map received following additions: - `all_privileges` - optional, bool - `on_all` - optional, bool, defaults to false @@ -88,7 +88,7 @@ For more information, refer to [variables.tf](variables.tf), list of inputs belo | [comment](#input\_comment) | Specifies a comment for the stage | `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 | | [copy\_options](#input\_copy\_options) | Specifies the copy options for the stage | `string` | `null` | no | -| [create\_default\_databse\_roles](#input\_create\_default\_databse\_roles) | Whether the default database roles should be created | `bool` | `false` | no | +| [create\_default\_database\_roles](#input\_create\_default\_database\_roles) | Whether the default database roles should be created | `bool` | `false` | no | | [credentials](#input\_credentials) | Specifies the credentials for the stage | `string` | `null` | no | | [database](#input\_database) | The database in which to create the stage | `string` | n/a | yes | | [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | @@ -107,7 +107,7 @@ For more information, refer to [variables.tf](variables.tf), list of inputs belo | [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 | -| [roles](#input\_roles) | Database roles created in the stage scope |
map(object({
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)
on_all = optional(bool, false)
schema_name = optional(string)
on_future = optional(bool, false)
}))
| `{}` | no | +| [roles](#input\_roles) | Database roles created in the stage scope |
map(object({
enabled = optional(bool, true)
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)
on_all = optional(bool, false)
schema_name = optional(string)
on_future = optional(bool, false)
}))
| `{}` | no | | [schema](#input\_schema) | The schema in which to create the stage | `string` | n/a | yes | | [snowflake\_iam\_user](#input\_snowflake\_iam\_user) | Specifies the Snowflake IAM user | `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 | @@ -130,7 +130,7 @@ For more information, refer to [variables.tf](variables.tf), list of inputs belo | Name | Description | |------|-------------| -| [databse\_roles](#output\_databse\_roles) | This stage access roles | +| [database\_roles](#output\_database\_roles) | This stage access roles | | [name](#output\_name) | Name of the stage | ## Providers diff --git a/examples/complete/main.tf b/examples/complete/main.tf index eb2e489..19af777 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -36,10 +36,10 @@ module "internal_stage" { comment = "This is my ingest stage" - create_default_databse_roles = true + create_default_database_roles = true roles = { - readonly = { # Modifies readonly default role + readonly = { # Modifies readonly default database role granted_to_database_roles = [ "${snowflake_database.this.name}.${snowflake_database_role.db_role_1.name}" ] @@ -49,12 +49,15 @@ module "internal_stage" { ] stage_grants = ["READ", "WRITE"] } - admin = { # Modifies admin default role + admin = { # Modifies admin default database role granted_database_roles = [ "${snowflake_database.this.name}.${snowflake_database_role.db_role_2.name}", ] } - role_1 = { # User created database role + readwrite = { + enabled = false # Disables readwrite default database role creation + } + role_1 = { # Database role created by user input granted_to_roles = [snowflake_role.role_1.name] granted_to_database_roles = ["${snowflake_database.this.name}.${snowflake_database_role.db_role_3.name}"] all_privileges = true @@ -62,7 +65,7 @@ module "internal_stage" { on_future = true on_all = true } - role_2 = { # User created database role + role_2 = { # Database role created by user input granted_to_database_roles = ["${snowflake_database.this.name}.${snowflake_database_role.db_role_3.name}"] stage_grants = ["READ", "WRITE"] with_grant_option = false @@ -71,5 +74,5 @@ module "internal_stage" { } } - stage_ownership_grant = "role_1" + stage_ownership_grant = "role_1" # When destroying, please read README.md } diff --git a/locals.tf b/locals.tf index 3b79b8e..eaf792a 100644 --- a/locals.tf +++ b/locals.tf @@ -9,14 +9,17 @@ locals { is_internal = var.url == null - default_roles_definition = var.create_default_databse_roles ? { + default_roles_definition = var.create_default_database_roles ? { readonly = { + enabled = true stage_grants = local.is_internal ? ["READ"] : ["USAGE"] } readwrite = { + enabled = true stage_grants = local.is_internal ? ["READ", "WRITE"] : ["USAGE"] } admin = { + enabled = true stage_grants = local.is_internal ? ["READ", "WRITE"] : ["USAGE"] } } : {} @@ -26,10 +29,9 @@ locals { if v != null } } - roles_definition = module.roles_deep_merge.merged - roles = { - for role_name, role in local.roles_definition : role_name => role + for role_name, role in module.roles_deep_merge.merged : role_name => role + if role_name != null && role.enabled } } diff --git a/outputs.tf b/outputs.tf index dfe3467..7d65885 100644 --- a/outputs.tf +++ b/outputs.tf @@ -3,7 +3,7 @@ output "name" { value = one(snowflake_stage.this[*].name) } -output "databse_roles" { +output "database_roles" { description = "This stage access roles" value = local.roles } diff --git a/variables.tf b/variables.tf index c9bd7f7..964e76d 100644 --- a/variables.tf +++ b/variables.tf @@ -74,7 +74,7 @@ variable "url" { default = null } -variable "create_default_databse_roles" { +variable "create_default_database_roles" { description = "Whether the default database roles should be created" type = bool default = false @@ -83,6 +83,7 @@ variable "create_default_databse_roles" { variable "roles" { description = "Database roles created in the stage scope" type = map(object({ + enabled = optional(bool, true) with_grant_option = optional(bool) granted_to_roles = optional(list(string)) granted_to_database_roles = optional(list(string))