From eaa366f9451c3dcb8c5ef116c3282fa1530c6a44 Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Wed, 19 Jul 2023 11:46:07 -0700 Subject: [PATCH 01/11] Refactor role grants to use new system with `grant_privileges_to_role` --- .../environments/dev/.terraform.lock.hcl | 30 ++-- terraform/snowflake/environments/dev/main.tf | 2 +- .../environments/prd/.terraform.lock.hcl | 30 ++-- terraform/snowflake/environments/prd/main.tf | 2 +- terraform/snowflake/modules/database/main.tf | 133 +++++++----------- terraform/snowflake/modules/elt/main.tf | 2 +- terraform/snowflake/modules/warehouse/main.tf | 16 ++- 7 files changed, 93 insertions(+), 122 deletions(-) diff --git a/terraform/snowflake/environments/dev/.terraform.lock.hcl b/terraform/snowflake/environments/dev/.terraform.lock.hcl index 46d0c89b..2d587176 100644 --- a/terraform/snowflake/environments/dev/.terraform.lock.hcl +++ b/terraform/snowflake/environments/dev/.terraform.lock.hcl @@ -2,23 +2,21 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/snowflake-labs/snowflake" { - version = "0.70.1" - constraints = "~> 0.61, 0.70.1" + version = "0.88.0" + constraints = "0.88.0, ~> 0.88" hashes = [ - "h1:+BPGXGbe1bECu58kdWNux5DXyP1W5Z8aq79e4uEpwHI=", - "h1:CRS1028YNlK6vChFtNJZmvhlYnQW6DKqK+oplakrps0=", - "h1:xI4ate6gEYzL6bhKKKeZCRnlgztAJXHqDL8tnetwXKo=", - "zh:1d90091270608000b1bf1e853a5eff378a310841355856dba406836db4c30125", - "zh:51742df503b9e6c0f4e0fccbb56400fa23b61e60779b3d14bef2e2a6fcbd7e95", - "zh:5cb3a110d5308becd41d54bf7a223ace6b413934bd53b4f2ee652774f1ed553b", - "zh:6e8df737f7328e67387c3fe68fad150832ca498abd858275b75b50cdf1ad6490", - "zh:78af0ffce8da39c6fcbddef5ecc608df10ca88c28c68b37e830d60a8f725341d", - "zh:800c66f900575731cac55023ea33ec1c8fb77ba64eac8c0211e1bb562ae25430", - "zh:89d2db56e891399cd99faf826259b12c80b5d4b002fa689094e6d20603aab25f", - "zh:a212204451dcbbaae5d4e7c91f3083b3f3a272b5c6e58e80a4f52c7c4aa1fcdd", - "zh:c0dce1ec1c7d8338de724318b126e506fe50117697f5799fac76c414acd34047", - "zh:cf8ad38cec31fd3d24c8e285d31d876009f42128da870cd38b827709821b0158", - "zh:de27e7f5c88d071d89bd561cf6d206adba012cc7b6540b3dfc01a99554529b5f", + "h1:qREluhKI48/JjHy0umPkUX0WDLE6xW/swUyczzG59WA=", + "zh:0c9e1e0596ca77cc03f911bc2d164a72a61ed40ed79956e5624fd6d054eefac9", + "zh:102b210ff3b464aea4992381fc63bd46ac92b38d85c1ce0bdca910604137b81e", + "zh:1182e368736807d4688a1483676917dbfb1400cfba1aa61845e18a9019660b8f", + "zh:12ad9acfaf91351799063c328d560b299a05e015af44d3c7189bfedc731a033a", + "zh:57e349019ecd59b0899bc2f2bd8c5f21d38f4d53ec2e84a659e5e1438e4d30c9", + "zh:8e03b5c2a7d16feb98b3b4c0de6270d14a649e9ccb7bcc13bbeac0960036f68e", + "zh:c7e3c8e45eb64ec3d25760f0f664d449b57c1a3d07c86f198cfb1aa69602464a", + "zh:d297c8338c39b84811cc6c9161da36f1bdd7ab71d9b48e15f37b734b4acd02c0", + "zh:e7bec6a0fd8aed7771898b8d4d3c9fa4e1974da15ae52cff3410ffdbc1e6e245", + "zh:ebd3858e0fabc5d3d8586a6446a29375241e776429af41490753b7171ef6f5f1", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f952e9bdd890f61d2f33ab15c10641dbcca0fc3735debd9ee5d1562fa3340582", ] } diff --git a/terraform/snowflake/environments/dev/main.tf b/terraform/snowflake/environments/dev/main.tf index b099ddf1..abb07814 100644 --- a/terraform/snowflake/environments/dev/main.tf +++ b/terraform/snowflake/environments/dev/main.tf @@ -20,7 +20,7 @@ terraform { required_providers { snowflake = { source = "Snowflake-Labs/snowflake" - version = "0.70.1" + version = "0.88" } } required_version = ">= 1.0" diff --git a/terraform/snowflake/environments/prd/.terraform.lock.hcl b/terraform/snowflake/environments/prd/.terraform.lock.hcl index 46d0c89b..2d587176 100644 --- a/terraform/snowflake/environments/prd/.terraform.lock.hcl +++ b/terraform/snowflake/environments/prd/.terraform.lock.hcl @@ -2,23 +2,21 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/snowflake-labs/snowflake" { - version = "0.70.1" - constraints = "~> 0.61, 0.70.1" + version = "0.88.0" + constraints = "0.88.0, ~> 0.88" hashes = [ - "h1:+BPGXGbe1bECu58kdWNux5DXyP1W5Z8aq79e4uEpwHI=", - "h1:CRS1028YNlK6vChFtNJZmvhlYnQW6DKqK+oplakrps0=", - "h1:xI4ate6gEYzL6bhKKKeZCRnlgztAJXHqDL8tnetwXKo=", - "zh:1d90091270608000b1bf1e853a5eff378a310841355856dba406836db4c30125", - "zh:51742df503b9e6c0f4e0fccbb56400fa23b61e60779b3d14bef2e2a6fcbd7e95", - "zh:5cb3a110d5308becd41d54bf7a223ace6b413934bd53b4f2ee652774f1ed553b", - "zh:6e8df737f7328e67387c3fe68fad150832ca498abd858275b75b50cdf1ad6490", - "zh:78af0ffce8da39c6fcbddef5ecc608df10ca88c28c68b37e830d60a8f725341d", - "zh:800c66f900575731cac55023ea33ec1c8fb77ba64eac8c0211e1bb562ae25430", - "zh:89d2db56e891399cd99faf826259b12c80b5d4b002fa689094e6d20603aab25f", - "zh:a212204451dcbbaae5d4e7c91f3083b3f3a272b5c6e58e80a4f52c7c4aa1fcdd", - "zh:c0dce1ec1c7d8338de724318b126e506fe50117697f5799fac76c414acd34047", - "zh:cf8ad38cec31fd3d24c8e285d31d876009f42128da870cd38b827709821b0158", - "zh:de27e7f5c88d071d89bd561cf6d206adba012cc7b6540b3dfc01a99554529b5f", + "h1:qREluhKI48/JjHy0umPkUX0WDLE6xW/swUyczzG59WA=", + "zh:0c9e1e0596ca77cc03f911bc2d164a72a61ed40ed79956e5624fd6d054eefac9", + "zh:102b210ff3b464aea4992381fc63bd46ac92b38d85c1ce0bdca910604137b81e", + "zh:1182e368736807d4688a1483676917dbfb1400cfba1aa61845e18a9019660b8f", + "zh:12ad9acfaf91351799063c328d560b299a05e015af44d3c7189bfedc731a033a", + "zh:57e349019ecd59b0899bc2f2bd8c5f21d38f4d53ec2e84a659e5e1438e4d30c9", + "zh:8e03b5c2a7d16feb98b3b4c0de6270d14a649e9ccb7bcc13bbeac0960036f68e", + "zh:c7e3c8e45eb64ec3d25760f0f664d449b57c1a3d07c86f198cfb1aa69602464a", + "zh:d297c8338c39b84811cc6c9161da36f1bdd7ab71d9b48e15f37b734b4acd02c0", + "zh:e7bec6a0fd8aed7771898b8d4d3c9fa4e1974da15ae52cff3410ffdbc1e6e245", + "zh:ebd3858e0fabc5d3d8586a6446a29375241e776429af41490753b7171ef6f5f1", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f952e9bdd890f61d2f33ab15c10641dbcca0fc3735debd9ee5d1562fa3340582", ] } diff --git a/terraform/snowflake/environments/prd/main.tf b/terraform/snowflake/environments/prd/main.tf index b099ddf1..abb07814 100644 --- a/terraform/snowflake/environments/prd/main.tf +++ b/terraform/snowflake/environments/prd/main.tf @@ -20,7 +20,7 @@ terraform { required_providers { snowflake = { source = "Snowflake-Labs/snowflake" - version = "0.70.1" + version = "0.88" } } required_version = ">= 1.0" diff --git a/terraform/snowflake/modules/database/main.tf b/terraform/snowflake/modules/database/main.tf index 22347e2c..7f9aeae8 100644 --- a/terraform/snowflake/modules/database/main.tf +++ b/terraform/snowflake/modules/database/main.tf @@ -6,7 +6,7 @@ terraform { required_providers { snowflake = { source = "Snowflake-Labs/snowflake" - version = "~> 0.61" + version = "~> 0.88" configuration_aliases = [ snowflake.securityadmin, snowflake.sysadmin, @@ -86,41 +86,6 @@ locals { READWRITE = ["SELECT", "REFERENCES"] READWRITECONTROL = ["SELECT", "REFERENCES", "OWNERSHIP"] } - - # Create objects for each access control - privilege combination. - # We will use them for assigning access role grants below. - database_permissions = flatten([ - for type in keys(local.database) : [ - for privilege in local.database[type] : { - type = type - privilege = privilege - } - ] - ]) - schema_permissions = flatten([ - for type in keys(local.schema) : [ - for privilege in local.schema[type] : { - type = type - privilege = privilege - } - ] - ]) - table_permissions = flatten([ - for type in keys(local.table) : [ - for privilege in local.table[type] : { - type = type - privilege = privilege - } - ] - ]) - view_permissions = flatten([ - for type in keys(local.view) : [ - for privilege in local.view[type] : { - type = type - privilege = privilege - } - ] - ]) } ####################################### @@ -175,59 +140,67 @@ resource "snowflake_role_grants" "this_to_sysadmin" { # https://community.snowflake.com/s/article/How-to-grant-select-on-all-future-tables-in-a-schema-and-database-level # Database grants -resource "snowflake_database_grant" "this" { - provider = snowflake.securityadmin - database_name = snowflake_database.this.name - for_each = { for p in local.database_permissions : "${p.type}-${p.privilege}" => p } - privilege = each.value.privilege - enable_multiple_grants = true - roles = ["${snowflake_database.this.name}_${each.value.type}"] - depends_on = [snowflake_role.this] +resource "snowflake_grant_privileges_to_role" "database" { + provider = snowflake.securityadmin + for_each = local.database + privileges = each.value + role_name = snowflake_role.this[each.key].name + on_account_object { + object_type = "DATABASE" + object_name = snowflake_database.this.name + } + with_grant_option = false } # Schema grants -resource "snowflake_schema_grant" "this" { - provider = snowflake.securityadmin - database_name = snowflake_database.this.name - for_each = { for p in local.schema_permissions : "${p.type}-${p.privilege}" => p } - privilege = each.value.privilege - enable_multiple_grants = true - on_future = true - roles = ["${snowflake_database.this.name}_${each.value.type}"] - depends_on = [snowflake_role.this] +resource "snowflake_grant_privileges_to_role" "schemas" { + provider = snowflake.securityadmin + for_each = local.schema + privileges = each.value + role_name = snowflake_role.this[each.key].name + on_schema { + future_schemas_in_database = snowflake_database.this.name + } + with_grant_option = false } -resource "snowflake_schema_grant" "public" { - provider = snowflake.securityadmin - database_name = snowflake_database.this.name - schema_name = "PUBLIC" - for_each = { for p in local.schema_permissions : "${p.type}-${p.privilege}" => p } - privilege = each.value.privilege - enable_multiple_grants = true - roles = ["${snowflake_database.this.name}_${each.value.type}"] - depends_on = [snowflake_role.this] +resource "snowflake_grant_privileges_to_role" "public" { + provider = snowflake.securityadmin + for_each = local.schema + privileges = each.value + role_name = snowflake_role.this[each.key].name + on_schema { + schema_name = "${snowflake_database.this.name}.PUBLIC" + } + with_grant_option = false } # Table grants -resource "snowflake_table_grant" "this" { - provider = snowflake.securityadmin - database_name = snowflake_database.this.name - for_each = { for p in local.table_permissions : "${p.type}-${p.privilege}" => p } - privilege = each.value.privilege - enable_multiple_grants = true - on_future = true - roles = ["${snowflake_database.this.name}_${each.value.type}"] - depends_on = [snowflake_role.this] +resource "snowflake_grant_privileges_to_role" "tables" { + provider = snowflake.securityadmin + for_each = local.table + privileges = each.value + role_name = snowflake_role.this[each.key].name + on_schema_object { + future { + object_type_plural = "TABLES" + in_database = snowflake_database.this.name + } + } + with_grant_option = false } # View grants -resource "snowflake_view_grant" "this" { - provider = snowflake.securityadmin - database_name = snowflake_database.this.name - for_each = { for p in local.view_permissions : "${p.type}-${p.privilege}" => p } - privilege = each.value.privilege - enable_multiple_grants = true - on_future = true - roles = ["${snowflake_database.this.name}_${each.value.type}"] - depends_on = [snowflake_role.this] +resource "snowflake_grant_privileges_to_role" "views" { + provider = snowflake.securityadmin + for_each = local.view + privileges = each.value + role_name = snowflake_role.this[each.key].name + on_schema_object { + future { + object_type_plural = "VIEWS" + in_database = snowflake_database.this.name + } + } + with_grant_option = false } diff --git a/terraform/snowflake/modules/elt/main.tf b/terraform/snowflake/modules/elt/main.tf index 54d23d95..cf6315a0 100644 --- a/terraform/snowflake/modules/elt/main.tf +++ b/terraform/snowflake/modules/elt/main.tf @@ -6,7 +6,7 @@ terraform { required_providers { snowflake = { source = "Snowflake-Labs/snowflake" - version = "~> 0.61" + version = "~> 0.88" configuration_aliases = [ snowflake.accountadmin, snowflake.securityadmin, diff --git a/terraform/snowflake/modules/warehouse/main.tf b/terraform/snowflake/modules/warehouse/main.tf index 62a06221..b3e1281a 100644 --- a/terraform/snowflake/modules/warehouse/main.tf +++ b/terraform/snowflake/modules/warehouse/main.tf @@ -6,7 +6,7 @@ terraform { required_providers { snowflake = { source = "Snowflake-Labs/snowflake" - version = "~> 0.61" + version = "~> 0.88" configuration_aliases = [ snowflake.securityadmin, snowflake.sysadmin, @@ -71,11 +71,13 @@ resource "snowflake_role_grants" "this_to_sysadmin" { # Warehouse Grants # ################################# -resource "snowflake_warehouse_grant" "this" { - provider = snowflake.securityadmin - for_each = toset(local.warehouse.MOU) - warehouse_name = snowflake_warehouse.this.name - privilege = each.key - roles = [snowflake_role.this.name] +resource "snowflake_grant_privileges_to_role" "this" { + provider = snowflake.securityadmin + privileges = local.warehouse.MOU + role_name = snowflake_role.this.name + on_account_object { + object_type = "WAREHOUSE" + object_name = snowflake_warehouse.this.name + } with_grant_option = false } From 58c56a7bbec9adb1bab0bfcb16f803ee732c0f59 Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Mon, 15 Apr 2024 15:04:47 -0700 Subject: [PATCH 02/11] Update role grants with new non-deprecated resources --- docs/snowflake.md | 55 +++--- terraform/snowflake/modules/database/main.tf | 66 +++---- terraform/snowflake/modules/elt/roles.tf | 187 ++++++++---------- terraform/snowflake/modules/elt/users.tf | 45 ++--- terraform/snowflake/modules/warehouse/main.tf | 17 +- 5 files changed, 169 insertions(+), 201 deletions(-) diff --git a/docs/snowflake.md b/docs/snowflake.md index 240ca2cb..bdca094d 100644 --- a/docs/snowflake.md +++ b/docs/snowflake.md @@ -196,14 +196,15 @@ The **elt** module has the following configuration: | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.0 | -| [snowflake](#requirement\_snowflake) | ~> 0.61 | +| [snowflake](#requirement\_snowflake) | ~> 0.88 | ## Providers | Name | Version | |------|---------| -| [snowflake.accountadmin](#provider\_snowflake.accountadmin) | ~> 0.61 | -| [snowflake.useradmin](#provider\_snowflake.useradmin) | ~> 0.61 | +| [snowflake](#provider\_snowflake) | ~> 0.88 | +| [snowflake.accountadmin](#provider\_snowflake.accountadmin) | ~> 0.88 | +| [snowflake.useradmin](#provider\_snowflake.useradmin) | ~> 0.88 | ## Modules @@ -221,35 +222,35 @@ The **elt** module has the following configuration: | Name | Type | |------|------| -| [snowflake_database_grant.this](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/database_grant) | resource | +| [snowflake_grant_account_role.analytics_r_to_reader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.analytics_r_to_reporter](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.analytics_rwc_to_transformer](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.loader_to_airflow](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.loader_to_fivetran](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.loader_to_sysadmin](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.loading_to_loader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.logger_to_accountadmin](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.logger_to_sentinel](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.logging_to_logger](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.raw_r_to_reader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.raw_r_to_transformer](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.raw_rwc_to_loader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.reader_to_github_ci](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.reader_to_sysadmin](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.reporter_to_sysadmin](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.reporting_to_reader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.reporting_to_reporter](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.transform_r_to_reader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.transform_rwc_to_transformer](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.transformer_to_dbt](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.transformer_to_sysadmin](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_account_role.transforming_to_transformer](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_account_role) | resource | +| [snowflake_grant_privileges_to_account_role.imported_privileges_to_logger](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_privileges_to_account_role) | resource | | [snowflake_role.loader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role) | resource | | [snowflake_role.logger](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role) | resource | | [snowflake_role.reader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role) | resource | | [snowflake_role.reporter](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role) | resource | | [snowflake_role.transformer](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role) | resource | -| [snowflake_role_grants.analytics_r_to_reader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.analytics_r_to_reporter](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.analytics_rwc_to_transformer](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.loader_to_airflow](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.loader_to_fivetran](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.loader_to_sysadmin](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.loading_to_loader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.logger_to_accountadmin](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.logger_to_sentinel](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.logging_to_logger](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.raw_r_to_reader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.raw_r_to_transformer](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.raw_rwc_to_loader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.reader_to_github_ci](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.reader_to_sysadmin](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.reporter_to_sysadmin](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.reporting_to_reader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.reporting_to_reporter](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.transform_r_to_reader](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.transform_rwc_to_transformer](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.transformer_to_dbt](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.transformer_to_sysadmin](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | -| [snowflake_role_grants.transforming_to_transformer](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | | [snowflake_user.airflow](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/user) | resource | | [snowflake_user.dbt](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/user) | resource | | [snowflake_user.fivetran](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/user) | resource | diff --git a/terraform/snowflake/modules/database/main.tf b/terraform/snowflake/modules/database/main.tf index 7f9aeae8..4956ed14 100644 --- a/terraform/snowflake/modules/database/main.tf +++ b/terraform/snowflake/modules/database/main.tf @@ -57,7 +57,6 @@ locals { "CREATE VIEW", "MODIFY", "MONITOR", - "OWNERSHIP", "USAGE", ] } @@ -74,7 +73,6 @@ locals { READWRITECONTROL = [ "DELETE", "INSERT", - "OWNERSHIP", "TRUNCATE", "UPDATE", ] @@ -84,7 +82,7 @@ locals { view = { READ = ["SELECT", "REFERENCES"] READWRITE = ["SELECT", "REFERENCES"] - READWRITECONTROL = ["SELECT", "REFERENCES", "OWNERSHIP"] + READWRITECONTROL = ["SELECT", "REFERENCES"] } } @@ -118,13 +116,11 @@ resource "snowflake_role" "this" { # Role Grants # ###################################### -resource "snowflake_role_grants" "this_to_sysadmin" { - provider = snowflake.useradmin - for_each = toset(keys(local.database)) - role_name = snowflake_role.this[each.key].name - enable_multiple_grants = true - roles = ["SYSADMIN"] - depends_on = [snowflake_role.this] +resource "snowflake_grant_account_role" "this_to_sysadmin" { + provider = snowflake.useradmin + for_each = toset(keys(local.database)) + role_name = snowflake_role.this[each.key].name + parent_role_name = "SYSADMIN" } ###################################### @@ -140,11 +136,11 @@ resource "snowflake_role_grants" "this_to_sysadmin" { # https://community.snowflake.com/s/article/How-to-grant-select-on-all-future-tables-in-a-schema-and-database-level # Database grants -resource "snowflake_grant_privileges_to_role" "database" { - provider = snowflake.securityadmin - for_each = local.database - privileges = each.value - role_name = snowflake_role.this[each.key].name +resource "snowflake_grant_privileges_to_account_role" "database" { + provider = snowflake.securityadmin + for_each = local.database + privileges = each.value + account_role_name = snowflake_role.this[each.key].name on_account_object { object_type = "DATABASE" object_name = snowflake_database.this.name @@ -153,22 +149,22 @@ resource "snowflake_grant_privileges_to_role" "database" { } # Schema grants -resource "snowflake_grant_privileges_to_role" "schemas" { - provider = snowflake.securityadmin - for_each = local.schema - privileges = each.value - role_name = snowflake_role.this[each.key].name +resource "snowflake_grant_privileges_to_account_role" "schemas" { + provider = snowflake.securityadmin + for_each = local.schema + privileges = each.value + account_role_name = snowflake_role.this[each.key].name on_schema { future_schemas_in_database = snowflake_database.this.name } with_grant_option = false } -resource "snowflake_grant_privileges_to_role" "public" { - provider = snowflake.securityadmin - for_each = local.schema - privileges = each.value - role_name = snowflake_role.this[each.key].name +resource "snowflake_grant_privileges_to_account_role" "public" { + provider = snowflake.securityadmin + for_each = local.schema + privileges = each.value + account_role_name = snowflake_role.this[each.key].name on_schema { schema_name = "${snowflake_database.this.name}.PUBLIC" } @@ -176,11 +172,11 @@ resource "snowflake_grant_privileges_to_role" "public" { } # Table grants -resource "snowflake_grant_privileges_to_role" "tables" { - provider = snowflake.securityadmin - for_each = local.table - privileges = each.value - role_name = snowflake_role.this[each.key].name +resource "snowflake_grant_privileges_to_account_role" "tables" { + provider = snowflake.securityadmin + for_each = local.table + privileges = each.value + account_role_name = snowflake_role.this[each.key].name on_schema_object { future { object_type_plural = "TABLES" @@ -191,11 +187,11 @@ resource "snowflake_grant_privileges_to_role" "tables" { } # View grants -resource "snowflake_grant_privileges_to_role" "views" { - provider = snowflake.securityadmin - for_each = local.view - privileges = each.value - role_name = snowflake_role.this[each.key].name +resource "snowflake_grant_privileges_to_account_role" "views" { + provider = snowflake.securityadmin + for_each = local.view + privileges = each.value + account_role_name = snowflake_role.this[each.key].name on_schema_object { future { object_type_plural = "VIEWS" diff --git a/terraform/snowflake/modules/elt/roles.tf b/terraform/snowflake/modules/elt/roles.tf index 47e0a12c..fb5575ed 100644 --- a/terraform/snowflake/modules/elt/roles.tf +++ b/terraform/snowflake/modules/elt/roles.tf @@ -52,149 +52,131 @@ resource "snowflake_role" "logger" { # https:#docs.snowflake.com/en/user-guide/security-access-control-considerations#aligning-object-access-with-business-functions # This allows SYSADMIN to make additional grants of database objects to these roles. -resource "snowflake_role_grants" "loader_to_sysadmin" { - provider = snowflake.useradmin - role_name = snowflake_role.loader.name - enable_multiple_grants = true - roles = ["SYSADMIN"] +resource "snowflake_grant_account_role" "loader_to_sysadmin" { + provider = snowflake.useradmin + role_name = snowflake_role.loader.name + parent_role_name = "SYSADMIN" } -resource "snowflake_role_grants" "transformer_to_sysadmin" { - provider = snowflake.useradmin - role_name = snowflake_role.transformer.name - enable_multiple_grants = true - roles = ["SYSADMIN"] +resource "snowflake_grant_account_role" "transformer_to_sysadmin" { + provider = snowflake.useradmin + role_name = snowflake_role.transformer.name + parent_role_name = "SYSADMIN" } -resource "snowflake_role_grants" "reporter_to_sysadmin" { - provider = snowflake.useradmin - role_name = snowflake_role.reporter.name - enable_multiple_grants = true - roles = ["SYSADMIN"] +resource "snowflake_grant_account_role" "reporter_to_sysadmin" { + provider = snowflake.useradmin + role_name = snowflake_role.reporter.name + parent_role_name = "SYSADMIN" } -resource "snowflake_role_grants" "reader_to_sysadmin" { - provider = snowflake.useradmin - role_name = snowflake_role.reader.name - enable_multiple_grants = true - roles = ["SYSADMIN"] +resource "snowflake_grant_account_role" "reader_to_sysadmin" { + provider = snowflake.useradmin + role_name = snowflake_role.reader.name + parent_role_name = "SYSADMIN" } # NOTE: logger has elevated privileges, so it is assigned # directly to accountadmin -resource "snowflake_role_grants" "logger_to_accountadmin" { - provider = snowflake.accountadmin - role_name = snowflake_role.logger.name - enable_multiple_grants = true - roles = ["SYSADMIN"] +resource "snowflake_grant_account_role" "logger_to_accountadmin" { + provider = snowflake.accountadmin + role_name = snowflake_role.logger.name + parent_role_name = "ACCOUNTADMIN" } # Loader has RWC privileges in RAW -resource "snowflake_role_grants" "raw_rwc_to_loader" { - provider = snowflake.useradmin - role_name = "${module.raw.name}_READWRITECONTROL" - enable_multiple_grants = true - roles = [snowflake_role.loader.name] +resource "snowflake_grant_account_role" "raw_rwc_to_loader" { + provider = snowflake.useradmin + role_name = "${module.raw.name}_READWRITECONTROL" + parent_role_name = snowflake_role.loader.name } # Reporter has read privileges in ANALYTICS -resource "snowflake_role_grants" "analytics_r_to_reporter" { - provider = snowflake.useradmin - role_name = "${module.analytics.name}_READ" - enable_multiple_grants = true - roles = [snowflake_role.reporter.name] +resource "snowflake_grant_account_role" "analytics_r_to_reporter" { + provider = snowflake.useradmin + role_name = "${module.analytics.name}_READ" + parent_role_name = snowflake_role.reporter.name } # Transformer has RWC privileges in TRANSFORM -resource "snowflake_role_grants" "transform_rwc_to_transformer" { - provider = snowflake.useradmin - role_name = "${module.transform.name}_READWRITECONTROL" - enable_multiple_grants = true - roles = [snowflake_role.transformer.name] +resource "snowflake_grant_account_role" "transform_rwc_to_transformer" { + provider = snowflake.useradmin + role_name = "${module.transform.name}_READWRITECONTROL" + parent_role_name = snowflake_role.transformer.name } # Transformer has RWC privileges in ANALYTICS -resource "snowflake_role_grants" "analytics_rwc_to_transformer" { - provider = snowflake.useradmin - role_name = "${module.analytics.name}_READWRITECONTROL" - enable_multiple_grants = true - roles = [snowflake_role.transformer.name] +resource "snowflake_grant_account_role" "analytics_rwc_to_transformer" { + provider = snowflake.useradmin + role_name = "${module.analytics.name}_READWRITECONTROL" + parent_role_name = snowflake_role.transformer.name } # Transformer has read permissions in RAW -resource "snowflake_role_grants" "raw_r_to_transformer" { - provider = snowflake.useradmin - role_name = "${module.raw.name}_READ" - enable_multiple_grants = true - roles = [snowflake_role.transformer.name] +resource "snowflake_grant_account_role" "raw_r_to_transformer" { + provider = snowflake.useradmin + role_name = "${module.raw.name}_READ" + parent_role_name = snowflake_role.transformer.name } # Transformer can use the TRANSFORMING warehouse -resource "snowflake_role_grants" "transforming_to_transformer" { - provider = snowflake.useradmin - for_each = toset(values(module.transforming)[*].access_role_name) - role_name = each.key - enable_multiple_grants = true - roles = [snowflake_role.transformer.name] +resource "snowflake_grant_account_role" "transforming_to_transformer" { + provider = snowflake.useradmin + for_each = toset(values(module.transforming)[*].access_role_name) + role_name = each.key + parent_role_name = snowflake_role.transformer.name } # Reporter can use the REPORTING warehouse -resource "snowflake_role_grants" "reporting_to_reporter" { - provider = snowflake.useradmin - for_each = toset(values(module.reporting)[*].access_role_name) - role_name = each.key - enable_multiple_grants = true - roles = [snowflake_role.reporter.name] +resource "snowflake_grant_account_role" "reporting_to_reporter" { + provider = snowflake.useradmin + for_each = toset(values(module.reporting)[*].access_role_name) + role_name = each.key + parent_role_name = snowflake_role.reporter.name } # Loader can use the LOADING warehouse -resource "snowflake_role_grants" "loading_to_loader" { - provider = snowflake.useradmin - for_each = toset(values(module.loading)[*].access_role_name) - role_name = each.key - enable_multiple_grants = true - roles = [snowflake_role.loader.name] +resource "snowflake_grant_account_role" "loading_to_loader" { + provider = snowflake.useradmin + for_each = toset(values(module.loading)[*].access_role_name) + role_name = each.key + parent_role_name = snowflake_role.loader.name } # Reader has read permissions in RAW -resource "snowflake_role_grants" "raw_r_to_reader" { - provider = snowflake.useradmin - role_name = "${module.raw.name}_READ" - enable_multiple_grants = true - roles = [snowflake_role.reader.name] +resource "snowflake_grant_account_role" "raw_r_to_reader" { + provider = snowflake.useradmin + role_name = "${module.raw.name}_READ" + parent_role_name = snowflake_role.reader.name } # Reader has read permissions in TRANSFORM -resource "snowflake_role_grants" "transform_r_to_reader" { - provider = snowflake.useradmin - role_name = "${module.transform.name}_READ" - enable_multiple_grants = true - roles = [snowflake_role.reader.name] +resource "snowflake_grant_account_role" "transform_r_to_reader" { + provider = snowflake.useradmin + role_name = "${module.transform.name}_READ" + parent_role_name = snowflake_role.reader.name } # Reader has read permissions in ANALYTICS -resource "snowflake_role_grants" "analytics_r_to_reader" { - provider = snowflake.useradmin - role_name = "${module.analytics.name}_READ" - enable_multiple_grants = true - roles = [snowflake_role.reader.name] +resource "snowflake_grant_account_role" "analytics_r_to_reader" { + provider = snowflake.useradmin + role_name = "${module.analytics.name}_READ" + parent_role_name = snowflake_role.reader.name } # Reader can use the REPORTING warehouse -resource "snowflake_role_grants" "reporting_to_reader" { - provider = snowflake.useradmin - for_each = toset(values(module.reporting)[*].access_role_name) - role_name = each.key - enable_multiple_grants = true - roles = [snowflake_role.reader.name] +resource "snowflake_grant_account_role" "reporting_to_reader" { + provider = snowflake.useradmin + for_each = toset(values(module.reporting)[*].access_role_name) + role_name = each.key + parent_role_name = snowflake_role.reader.name } # Logger can use the LOGGING warehouse -resource "snowflake_role_grants" "logging_to_logger" { - provider = snowflake.useradmin - role_name = module.logging.access_role_name - enable_multiple_grants = true - roles = [snowflake_role.logger.name] +resource "snowflake_grant_account_role" "logging_to_logger" { + provider = snowflake.useradmin + role_name = module.logging.access_role_name + parent_role_name = snowflake_role.logger.name } ###################################### @@ -202,16 +184,11 @@ resource "snowflake_role_grants" "logging_to_logger" { ###################################### # Imported privileges for logging -resource "snowflake_database_grant" "this" { - provider = snowflake.accountadmin - database_name = "SNOWFLAKE" - privilege = "IMPORTED PRIVILEGES" - enable_multiple_grants = true - roles = [snowflake_role.logger.name] - # Sigh... we need to ignore changes because the terraform provider doesn't - # properly track this resource: - # https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1998 - lifecycle { - ignore_changes = all +resource "snowflake_grant_privileges_to_account_role" "imported_privileges_to_logger" { + account_role_name = snowflake_role.logger.name + privileges = ["IMPORTED PRIVILEGES"] + on_account_object { + object_type = "DATABASE" + object_name = "SNOWFLAKE" } } diff --git a/terraform/snowflake/modules/elt/users.tf b/terraform/snowflake/modules/elt/users.tf index 6ae11d21..2976a0f3 100644 --- a/terraform/snowflake/modules/elt/users.tf +++ b/terraform/snowflake/modules/elt/users.tf @@ -62,37 +62,32 @@ resource "snowflake_user" "sentinel" { # Role Grants # ###################################### -resource "snowflake_role_grants" "transformer_to_dbt" { - provider = snowflake.useradmin - role_name = snowflake_role.transformer.name - enable_multiple_grants = true - users = [snowflake_user.dbt.name] +resource "snowflake_grant_account_role" "transformer_to_dbt" { + provider = snowflake.useradmin + role_name = snowflake_role.transformer.name + user_name = snowflake_user.dbt.name } -resource "snowflake_role_grants" "loader_to_airflow" { - provider = snowflake.useradmin - role_name = snowflake_role.loader.name - enable_multiple_grants = true - users = [snowflake_user.airflow.name] +resource "snowflake_grant_account_role" "loader_to_airflow" { + provider = snowflake.useradmin + role_name = snowflake_role.loader.name + user_name = snowflake_user.airflow.name } -resource "snowflake_role_grants" "loader_to_fivetran" { - provider = snowflake.useradmin - role_name = snowflake_role.loader.name - enable_multiple_grants = true - users = [snowflake_user.fivetran.name] +resource "snowflake_grant_account_role" "loader_to_fivetran" { + provider = snowflake.useradmin + role_name = snowflake_role.loader.name + user_name = snowflake_user.fivetran.name } -resource "snowflake_role_grants" "reader_to_github_ci" { - provider = snowflake.useradmin - role_name = snowflake_role.reader.name - enable_multiple_grants = true - users = [snowflake_user.github_ci.name] +resource "snowflake_grant_account_role" "reader_to_github_ci" { + provider = snowflake.useradmin + role_name = snowflake_role.reader.name + user_name = snowflake_user.github_ci.name } -resource "snowflake_role_grants" "logger_to_sentinel" { - provider = snowflake.useradmin - role_name = snowflake_role.logger.name - enable_multiple_grants = true - users = [snowflake_user.sentinel.name] +resource "snowflake_grant_account_role" "logger_to_sentinel" { + provider = snowflake.useradmin + role_name = snowflake_role.logger.name + user_name = snowflake_user.sentinel.name } diff --git a/terraform/snowflake/modules/warehouse/main.tf b/terraform/snowflake/modules/warehouse/main.tf index b3e1281a..c8b2e909 100644 --- a/terraform/snowflake/modules/warehouse/main.tf +++ b/terraform/snowflake/modules/warehouse/main.tf @@ -60,21 +60,20 @@ resource "snowflake_role" "this" { # Role Grants # ################################# -resource "snowflake_role_grants" "this_to_sysadmin" { - provider = snowflake.useradmin - role_name = snowflake_role.this.name - enable_multiple_grants = true - roles = ["SYSADMIN"] +resource "snowflake_grant_account_role" "this_to_sysadmin" { + provider = snowflake.useradmin + role_name = snowflake_role.this.name + parent_role_name = "SYSADMIN" } ################################# # Warehouse Grants # ################################# -resource "snowflake_grant_privileges_to_role" "this" { - provider = snowflake.securityadmin - privileges = local.warehouse.MOU - role_name = snowflake_role.this.name +resource "snowflake_grant_privileges_to_account_role" "this" { + provider = snowflake.securityadmin + privileges = local.warehouse.MOU + account_role_name = snowflake_role.this.name on_account_object { object_type = "WAREHOUSE" object_name = snowflake_warehouse.this.name From 469c7c9f1f28f414edb25ae675ecc555534c4feb Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Mon, 15 Apr 2024 15:42:35 -0700 Subject: [PATCH 03/11] Add todo --- terraform/snowflake/modules/database/main.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/terraform/snowflake/modules/database/main.tf b/terraform/snowflake/modules/database/main.tf index 4956ed14..b7f22b2d 100644 --- a/terraform/snowflake/modules/database/main.tf +++ b/terraform/snowflake/modules/database/main.tf @@ -135,6 +135,8 @@ resource "snowflake_grant_account_role" "this_to_sysadmin" { # roles created here also get the same permissions in newly-created schemas and tables. # https://community.snowflake.com/s/article/How-to-grant-select-on-all-future-tables-in-a-schema-and-database-level +# TODO: ownership grants on all and future tables + # Database grants resource "snowflake_grant_privileges_to_account_role" "database" { provider = snowflake.securityadmin From 3e4babe931dc4e7a314d4247bf29ec0058c50c40 Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Fri, 4 Oct 2024 14:13:27 -0700 Subject: [PATCH 04/11] Implement ownership on future objects --- terraform/snowflake/modules/database/main.tf | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/terraform/snowflake/modules/database/main.tf b/terraform/snowflake/modules/database/main.tf index b7f22b2d..48a917ba 100644 --- a/terraform/snowflake/modules/database/main.tf +++ b/terraform/snowflake/modules/database/main.tf @@ -151,6 +151,17 @@ resource "snowflake_grant_privileges_to_account_role" "database" { } # Schema grants +resource "snowflake_grant_ownership" "schemas" { + provider = snowflake.sysadmin + account_role_name = snowflake_role.this["READWRITECONTROL"].name + on { + future { + object_type_plural = "SCHEMAS" + in_database = snowflake_database.this.name + } + } +} + resource "snowflake_grant_privileges_to_account_role" "schemas" { provider = snowflake.securityadmin for_each = local.schema @@ -174,6 +185,17 @@ resource "snowflake_grant_privileges_to_account_role" "public" { } # Table grants +resource "snowflake_grant_ownership" "tables" { + provider = snowflake.sysadmin + account_role_name = snowflake_role.this["READWRITECONTROL"].name + on { + future { + object_type_plural = "TABLES" + in_database = snowflake_database.this.name + } + } +} + resource "snowflake_grant_privileges_to_account_role" "tables" { provider = snowflake.securityadmin for_each = local.table @@ -189,6 +211,17 @@ resource "snowflake_grant_privileges_to_account_role" "tables" { } # View grants +resource "snowflake_grant_ownership" "views" { + provider = snowflake.sysadmin + account_role_name = snowflake_role.this["READWRITECONTROL"].name + on { + future { + object_type_plural = "VIEWS" + in_database = snowflake_database.this.name + } + } +} + resource "snowflake_grant_privileges_to_account_role" "views" { provider = snowflake.securityadmin for_each = local.view From 4e744749279e5e2e6ccaf2c374b9be202cfc4221 Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Fri, 4 Oct 2024 15:42:34 -0700 Subject: [PATCH 05/11] Securityadmin for ownership change --- terraform/snowflake/modules/database/main.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/terraform/snowflake/modules/database/main.tf b/terraform/snowflake/modules/database/main.tf index 48a917ba..fa4bf19a 100644 --- a/terraform/snowflake/modules/database/main.tf +++ b/terraform/snowflake/modules/database/main.tf @@ -152,7 +152,7 @@ resource "snowflake_grant_privileges_to_account_role" "database" { # Schema grants resource "snowflake_grant_ownership" "schemas" { - provider = snowflake.sysadmin + provider = snowflake.securityadmin account_role_name = snowflake_role.this["READWRITECONTROL"].name on { future { @@ -186,7 +186,7 @@ resource "snowflake_grant_privileges_to_account_role" "public" { # Table grants resource "snowflake_grant_ownership" "tables" { - provider = snowflake.sysadmin + provider = snowflake.securityadmin account_role_name = snowflake_role.this["READWRITECONTROL"].name on { future { @@ -212,7 +212,7 @@ resource "snowflake_grant_privileges_to_account_role" "tables" { # View grants resource "snowflake_grant_ownership" "views" { - provider = snowflake.sysadmin + provider = snowflake.securityadmin account_role_name = snowflake_role.this["READWRITECONTROL"].name on { future { From ca7d7a17eb888f8f04646aba080610fed2dd007e Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Mon, 7 Oct 2024 16:59:22 -0700 Subject: [PATCH 06/11] Accountadmin for granting imported privileges --- terraform/snowflake/modules/database/main.tf | 2 +- terraform/snowflake/modules/elt/roles.tf | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/terraform/snowflake/modules/database/main.tf b/terraform/snowflake/modules/database/main.tf index fa4bf19a..03bb7ccb 100644 --- a/terraform/snowflake/modules/database/main.tf +++ b/terraform/snowflake/modules/database/main.tf @@ -97,7 +97,7 @@ resource "snowflake_database" "this" { data_retention_time_in_days = var.data_retention_time_in_days lifecycle { - prevent_destroy = true + prevent_destroy = false } } diff --git a/terraform/snowflake/modules/elt/roles.tf b/terraform/snowflake/modules/elt/roles.tf index fb5575ed..a84e3929 100644 --- a/terraform/snowflake/modules/elt/roles.tf +++ b/terraform/snowflake/modules/elt/roles.tf @@ -185,6 +185,7 @@ resource "snowflake_grant_account_role" "logging_to_logger" { # Imported privileges for logging resource "snowflake_grant_privileges_to_account_role" "imported_privileges_to_logger" { + provider = snowflake.accountadmin account_role_name = snowflake_role.logger.name privileges = ["IMPORTED PRIVILEGES"] on_account_object { From dd9918721f9b48d35f276291eed39137dc048ae4 Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Mon, 7 Oct 2024 17:25:46 -0700 Subject: [PATCH 07/11] snowflake_role has been renamed to snowflake_account_role --- terraform/snowflake/modules/database/main.tf | 20 ++++---- terraform/snowflake/modules/elt/roles.tf | 48 +++++++++---------- terraform/snowflake/modules/elt/users.tf | 20 ++++---- terraform/snowflake/modules/warehouse/main.tf | 6 +-- .../snowflake/modules/warehouse/outputs.tf | 2 +- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/terraform/snowflake/modules/database/main.tf b/terraform/snowflake/modules/database/main.tf index 03bb7ccb..ce8c136d 100644 --- a/terraform/snowflake/modules/database/main.tf +++ b/terraform/snowflake/modules/database/main.tf @@ -105,7 +105,7 @@ resource "snowflake_database" "this" { # Access Roles # ###################################### -resource "snowflake_role" "this" { +resource "snowflake_account_role" "this" { provider = snowflake.useradmin for_each = toset(keys(local.database)) name = "${snowflake_database.this.name}_${each.key}" @@ -119,7 +119,7 @@ resource "snowflake_role" "this" { resource "snowflake_grant_account_role" "this_to_sysadmin" { provider = snowflake.useradmin for_each = toset(keys(local.database)) - role_name = snowflake_role.this[each.key].name + role_name = snowflake_account_role.this[each.key].name parent_role_name = "SYSADMIN" } @@ -142,7 +142,7 @@ resource "snowflake_grant_privileges_to_account_role" "database" { provider = snowflake.securityadmin for_each = local.database privileges = each.value - account_role_name = snowflake_role.this[each.key].name + account_role_name = snowflake_account_role.this[each.key].name on_account_object { object_type = "DATABASE" object_name = snowflake_database.this.name @@ -153,7 +153,7 @@ resource "snowflake_grant_privileges_to_account_role" "database" { # Schema grants resource "snowflake_grant_ownership" "schemas" { provider = snowflake.securityadmin - account_role_name = snowflake_role.this["READWRITECONTROL"].name + account_role_name = snowflake_account_role.this["READWRITECONTROL"].name on { future { object_type_plural = "SCHEMAS" @@ -166,7 +166,7 @@ resource "snowflake_grant_privileges_to_account_role" "schemas" { provider = snowflake.securityadmin for_each = local.schema privileges = each.value - account_role_name = snowflake_role.this[each.key].name + account_role_name = snowflake_account_role.this[each.key].name on_schema { future_schemas_in_database = snowflake_database.this.name } @@ -177,7 +177,7 @@ resource "snowflake_grant_privileges_to_account_role" "public" { provider = snowflake.securityadmin for_each = local.schema privileges = each.value - account_role_name = snowflake_role.this[each.key].name + account_role_name = snowflake_account_role.this[each.key].name on_schema { schema_name = "${snowflake_database.this.name}.PUBLIC" } @@ -187,7 +187,7 @@ resource "snowflake_grant_privileges_to_account_role" "public" { # Table grants resource "snowflake_grant_ownership" "tables" { provider = snowflake.securityadmin - account_role_name = snowflake_role.this["READWRITECONTROL"].name + account_role_name = snowflake_account_role.this["READWRITECONTROL"].name on { future { object_type_plural = "TABLES" @@ -200,7 +200,7 @@ resource "snowflake_grant_privileges_to_account_role" "tables" { provider = snowflake.securityadmin for_each = local.table privileges = each.value - account_role_name = snowflake_role.this[each.key].name + account_role_name = snowflake_account_role.this[each.key].name on_schema_object { future { object_type_plural = "TABLES" @@ -213,7 +213,7 @@ resource "snowflake_grant_privileges_to_account_role" "tables" { # View grants resource "snowflake_grant_ownership" "views" { provider = snowflake.securityadmin - account_role_name = snowflake_role.this["READWRITECONTROL"].name + account_role_name = snowflake_account_role.this["READWRITECONTROL"].name on { future { object_type_plural = "VIEWS" @@ -226,7 +226,7 @@ resource "snowflake_grant_privileges_to_account_role" "views" { provider = snowflake.securityadmin for_each = local.view privileges = each.value - account_role_name = snowflake_role.this[each.key].name + account_role_name = snowflake_account_role.this[each.key].name on_schema_object { future { object_type_plural = "VIEWS" diff --git a/terraform/snowflake/modules/elt/roles.tf b/terraform/snowflake/modules/elt/roles.tf index a84e3929..0bed3047 100644 --- a/terraform/snowflake/modules/elt/roles.tf +++ b/terraform/snowflake/modules/elt/roles.tf @@ -5,7 +5,7 @@ # The loader persona is for tools like Airflow or Fivetran, which load # raw data into Snowflake for later processing. It has read/write/control # permissions in RAW. -resource "snowflake_role" "loader" { +resource "snowflake_account_role" "loader" { provider = snowflake.useradmin name = "LOADER_${var.environment}" comment = "Permissions to load data to the ${module.raw.name} database" @@ -14,7 +14,7 @@ resource "snowflake_role" "loader" { # The transformer persona is for in-warehouse data transformations. Most analytics # engineers will use this role, as will dbt robot users. It has read/write/control # permissions in ANALYTICS and TRANSFORM, as well as read permissions in RAW. -resource "snowflake_role" "transformer" { +resource "snowflake_account_role" "transformer" { provider = snowflake.useradmin name = "TRANSFORMER_${var.environment}" comment = "Permissions to read data from the ${module.raw.name} database, and read/write to ${module.transform.name} and ${module.analytics.name}" @@ -22,7 +22,7 @@ resource "snowflake_role" "transformer" { # The reporter persona is for BI tools to consume analysis-ready tables in the # analytics databse. It has read permissions in ANALYTICS. -resource "snowflake_role" "reporter" { +resource "snowflake_account_role" "reporter" { provider = snowflake.useradmin name = "REPORTER_${var.environment}" comment = "Permissions to read data from the ${module.analytics.name} database" @@ -30,7 +30,7 @@ resource "snowflake_role" "reporter" { # The reader persona is for CI tools to be able to reflect on the databases. # TODO: can we restrict the permissions for this role to just REFERENCES? -resource "snowflake_role" "reader" { +resource "snowflake_account_role" "reader" { provider = snowflake.useradmin name = "READER_${var.environment}" comment = "Permissions to read ${module.analytics.name}, ${module.transform.name}, and ${module.raw.name} for CI purposes" @@ -38,7 +38,7 @@ resource "snowflake_role" "reader" { # The logger role is for logging solutions like Sentinel to introspect # things like usage and access. -resource "snowflake_role" "logger" { +resource "snowflake_account_role" "logger" { provider = snowflake.useradmin name = "LOGGER_${var.environment}" comment = "Permissions to read the SNOWFLAKE metadatabase for logging purposes" @@ -54,25 +54,25 @@ resource "snowflake_role" "logger" { resource "snowflake_grant_account_role" "loader_to_sysadmin" { provider = snowflake.useradmin - role_name = snowflake_role.loader.name + role_name = snowflake_account_role.loader.name parent_role_name = "SYSADMIN" } resource "snowflake_grant_account_role" "transformer_to_sysadmin" { provider = snowflake.useradmin - role_name = snowflake_role.transformer.name + role_name = snowflake_account_role.transformer.name parent_role_name = "SYSADMIN" } resource "snowflake_grant_account_role" "reporter_to_sysadmin" { provider = snowflake.useradmin - role_name = snowflake_role.reporter.name + role_name = snowflake_account_role.reporter.name parent_role_name = "SYSADMIN" } resource "snowflake_grant_account_role" "reader_to_sysadmin" { provider = snowflake.useradmin - role_name = snowflake_role.reader.name + role_name = snowflake_account_role.reader.name parent_role_name = "SYSADMIN" } @@ -80,7 +80,7 @@ resource "snowflake_grant_account_role" "reader_to_sysadmin" { # directly to accountadmin resource "snowflake_grant_account_role" "logger_to_accountadmin" { provider = snowflake.accountadmin - role_name = snowflake_role.logger.name + role_name = snowflake_account_role.logger.name parent_role_name = "ACCOUNTADMIN" } @@ -88,35 +88,35 @@ resource "snowflake_grant_account_role" "logger_to_accountadmin" { resource "snowflake_grant_account_role" "raw_rwc_to_loader" { provider = snowflake.useradmin role_name = "${module.raw.name}_READWRITECONTROL" - parent_role_name = snowflake_role.loader.name + parent_role_name = snowflake_account_role.loader.name } # Reporter has read privileges in ANALYTICS resource "snowflake_grant_account_role" "analytics_r_to_reporter" { provider = snowflake.useradmin role_name = "${module.analytics.name}_READ" - parent_role_name = snowflake_role.reporter.name + parent_role_name = snowflake_account_role.reporter.name } # Transformer has RWC privileges in TRANSFORM resource "snowflake_grant_account_role" "transform_rwc_to_transformer" { provider = snowflake.useradmin role_name = "${module.transform.name}_READWRITECONTROL" - parent_role_name = snowflake_role.transformer.name + parent_role_name = snowflake_account_role.transformer.name } # Transformer has RWC privileges in ANALYTICS resource "snowflake_grant_account_role" "analytics_rwc_to_transformer" { provider = snowflake.useradmin role_name = "${module.analytics.name}_READWRITECONTROL" - parent_role_name = snowflake_role.transformer.name + parent_role_name = snowflake_account_role.transformer.name } # Transformer has read permissions in RAW resource "snowflake_grant_account_role" "raw_r_to_transformer" { provider = snowflake.useradmin role_name = "${module.raw.name}_READ" - parent_role_name = snowflake_role.transformer.name + parent_role_name = snowflake_account_role.transformer.name } # Transformer can use the TRANSFORMING warehouse @@ -124,7 +124,7 @@ resource "snowflake_grant_account_role" "transforming_to_transformer" { provider = snowflake.useradmin for_each = toset(values(module.transforming)[*].access_role_name) role_name = each.key - parent_role_name = snowflake_role.transformer.name + parent_role_name = snowflake_account_role.transformer.name } # Reporter can use the REPORTING warehouse @@ -132,7 +132,7 @@ resource "snowflake_grant_account_role" "reporting_to_reporter" { provider = snowflake.useradmin for_each = toset(values(module.reporting)[*].access_role_name) role_name = each.key - parent_role_name = snowflake_role.reporter.name + parent_role_name = snowflake_account_role.reporter.name } # Loader can use the LOADING warehouse @@ -140,28 +140,28 @@ resource "snowflake_grant_account_role" "loading_to_loader" { provider = snowflake.useradmin for_each = toset(values(module.loading)[*].access_role_name) role_name = each.key - parent_role_name = snowflake_role.loader.name + parent_role_name = snowflake_account_role.loader.name } # Reader has read permissions in RAW resource "snowflake_grant_account_role" "raw_r_to_reader" { provider = snowflake.useradmin role_name = "${module.raw.name}_READ" - parent_role_name = snowflake_role.reader.name + parent_role_name = snowflake_account_role.reader.name } # Reader has read permissions in TRANSFORM resource "snowflake_grant_account_role" "transform_r_to_reader" { provider = snowflake.useradmin role_name = "${module.transform.name}_READ" - parent_role_name = snowflake_role.reader.name + parent_role_name = snowflake_account_role.reader.name } # Reader has read permissions in ANALYTICS resource "snowflake_grant_account_role" "analytics_r_to_reader" { provider = snowflake.useradmin role_name = "${module.analytics.name}_READ" - parent_role_name = snowflake_role.reader.name + parent_role_name = snowflake_account_role.reader.name } # Reader can use the REPORTING warehouse @@ -169,14 +169,14 @@ resource "snowflake_grant_account_role" "reporting_to_reader" { provider = snowflake.useradmin for_each = toset(values(module.reporting)[*].access_role_name) role_name = each.key - parent_role_name = snowflake_role.reader.name + parent_role_name = snowflake_account_role.reader.name } # Logger can use the LOGGING warehouse resource "snowflake_grant_account_role" "logging_to_logger" { provider = snowflake.useradmin role_name = module.logging.access_role_name - parent_role_name = snowflake_role.logger.name + parent_role_name = snowflake_account_role.logger.name } ###################################### @@ -186,7 +186,7 @@ resource "snowflake_grant_account_role" "logging_to_logger" { # Imported privileges for logging resource "snowflake_grant_privileges_to_account_role" "imported_privileges_to_logger" { provider = snowflake.accountadmin - account_role_name = snowflake_role.logger.name + account_role_name = snowflake_account_role.logger.name privileges = ["IMPORTED PRIVILEGES"] on_account_object { object_type = "DATABASE" diff --git a/terraform/snowflake/modules/elt/users.tf b/terraform/snowflake/modules/elt/users.tf index 2976a0f3..986c9453 100644 --- a/terraform/snowflake/modules/elt/users.tf +++ b/terraform/snowflake/modules/elt/users.tf @@ -8,7 +8,7 @@ resource "snowflake_user" "dbt" { comment = "Service user for dbt Cloud" default_warehouse = module.transforming["XS"].name - default_role = snowflake_role.transformer.name + default_role = snowflake_account_role.transformer.name must_change_password = false } @@ -20,7 +20,7 @@ resource "snowflake_user" "airflow" { comment = "Service user for Airflow" default_warehouse = module.loading["XS"].name - default_role = snowflake_role.loader.name + default_role = snowflake_account_role.loader.name must_change_password = false } @@ -31,7 +31,7 @@ resource "snowflake_user" "fivetran" { comment = "Service user for Fivetran" default_warehouse = module.loading["XS"].name - default_role = snowflake_role.loader.name + default_role = snowflake_account_role.loader.name must_change_password = false } @@ -42,7 +42,7 @@ resource "snowflake_user" "github_ci" { comment = "Service user for GitHub CI" default_warehouse = module.reporting["XS"].name - default_role = snowflake_role.reader.name + default_role = snowflake_account_role.reader.name must_change_password = false } @@ -53,7 +53,7 @@ resource "snowflake_user" "sentinel" { comment = "Service user for Sentinel" default_warehouse = module.logging.name - default_role = snowflake_role.logger.name + default_role = snowflake_account_role.logger.name must_change_password = false } @@ -64,30 +64,30 @@ resource "snowflake_user" "sentinel" { resource "snowflake_grant_account_role" "transformer_to_dbt" { provider = snowflake.useradmin - role_name = snowflake_role.transformer.name + role_name = snowflake_account_role.transformer.name user_name = snowflake_user.dbt.name } resource "snowflake_grant_account_role" "loader_to_airflow" { provider = snowflake.useradmin - role_name = snowflake_role.loader.name + role_name = snowflake_account_role.loader.name user_name = snowflake_user.airflow.name } resource "snowflake_grant_account_role" "loader_to_fivetran" { provider = snowflake.useradmin - role_name = snowflake_role.loader.name + role_name = snowflake_account_role.loader.name user_name = snowflake_user.fivetran.name } resource "snowflake_grant_account_role" "reader_to_github_ci" { provider = snowflake.useradmin - role_name = snowflake_role.reader.name + role_name = snowflake_account_role.reader.name user_name = snowflake_user.github_ci.name } resource "snowflake_grant_account_role" "logger_to_sentinel" { provider = snowflake.useradmin - role_name = snowflake_role.logger.name + role_name = snowflake_account_role.logger.name user_name = snowflake_user.sentinel.name } diff --git a/terraform/snowflake/modules/warehouse/main.tf b/terraform/snowflake/modules/warehouse/main.tf index c8b2e909..30671262 100644 --- a/terraform/snowflake/modules/warehouse/main.tf +++ b/terraform/snowflake/modules/warehouse/main.tf @@ -50,7 +50,7 @@ resource "snowflake_warehouse" "this" { ################################# # Monitoring, usage, and operating permissions for the LOADING warehouse. -resource "snowflake_role" "this" { +resource "snowflake_account_role" "this" { name = "${var.name}_WH_MOU" provider = snowflake.useradmin comment = "Monitoring, usage, and operating permissions for the ${var.name} warehouse" @@ -62,7 +62,7 @@ resource "snowflake_role" "this" { resource "snowflake_grant_account_role" "this_to_sysadmin" { provider = snowflake.useradmin - role_name = snowflake_role.this.name + role_name = snowflake_account_role.this.name parent_role_name = "SYSADMIN" } @@ -73,7 +73,7 @@ resource "snowflake_grant_account_role" "this_to_sysadmin" { resource "snowflake_grant_privileges_to_account_role" "this" { provider = snowflake.securityadmin privileges = local.warehouse.MOU - account_role_name = snowflake_role.this.name + account_role_name = snowflake_account_role.this.name on_account_object { object_type = "WAREHOUSE" object_name = snowflake_warehouse.this.name diff --git a/terraform/snowflake/modules/warehouse/outputs.tf b/terraform/snowflake/modules/warehouse/outputs.tf index 4ab74254..a88df60a 100644 --- a/terraform/snowflake/modules/warehouse/outputs.tf +++ b/terraform/snowflake/modules/warehouse/outputs.tf @@ -1,6 +1,6 @@ output "access_role_name" { description = "Warehouse access_role" - value = snowflake_role.this.name + value = snowflake_account_role.this.name } output "name" { From 8a31c21a467db3a2ff382ed94363ca42c635c031 Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Tue, 8 Oct 2024 08:50:39 -0700 Subject: [PATCH 08/11] Revert "snowflake_role has been renamed to snowflake_account_role" This reverts commit dd9918721f9b48d35f276291eed39137dc048ae4. --- terraform/snowflake/modules/database/main.tf | 20 ++++---- terraform/snowflake/modules/elt/roles.tf | 48 +++++++++---------- terraform/snowflake/modules/elt/users.tf | 20 ++++---- terraform/snowflake/modules/warehouse/main.tf | 6 +-- .../snowflake/modules/warehouse/outputs.tf | 2 +- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/terraform/snowflake/modules/database/main.tf b/terraform/snowflake/modules/database/main.tf index ce8c136d..03bb7ccb 100644 --- a/terraform/snowflake/modules/database/main.tf +++ b/terraform/snowflake/modules/database/main.tf @@ -105,7 +105,7 @@ resource "snowflake_database" "this" { # Access Roles # ###################################### -resource "snowflake_account_role" "this" { +resource "snowflake_role" "this" { provider = snowflake.useradmin for_each = toset(keys(local.database)) name = "${snowflake_database.this.name}_${each.key}" @@ -119,7 +119,7 @@ resource "snowflake_account_role" "this" { resource "snowflake_grant_account_role" "this_to_sysadmin" { provider = snowflake.useradmin for_each = toset(keys(local.database)) - role_name = snowflake_account_role.this[each.key].name + role_name = snowflake_role.this[each.key].name parent_role_name = "SYSADMIN" } @@ -142,7 +142,7 @@ resource "snowflake_grant_privileges_to_account_role" "database" { provider = snowflake.securityadmin for_each = local.database privileges = each.value - account_role_name = snowflake_account_role.this[each.key].name + account_role_name = snowflake_role.this[each.key].name on_account_object { object_type = "DATABASE" object_name = snowflake_database.this.name @@ -153,7 +153,7 @@ resource "snowflake_grant_privileges_to_account_role" "database" { # Schema grants resource "snowflake_grant_ownership" "schemas" { provider = snowflake.securityadmin - account_role_name = snowflake_account_role.this["READWRITECONTROL"].name + account_role_name = snowflake_role.this["READWRITECONTROL"].name on { future { object_type_plural = "SCHEMAS" @@ -166,7 +166,7 @@ resource "snowflake_grant_privileges_to_account_role" "schemas" { provider = snowflake.securityadmin for_each = local.schema privileges = each.value - account_role_name = snowflake_account_role.this[each.key].name + account_role_name = snowflake_role.this[each.key].name on_schema { future_schemas_in_database = snowflake_database.this.name } @@ -177,7 +177,7 @@ resource "snowflake_grant_privileges_to_account_role" "public" { provider = snowflake.securityadmin for_each = local.schema privileges = each.value - account_role_name = snowflake_account_role.this[each.key].name + account_role_name = snowflake_role.this[each.key].name on_schema { schema_name = "${snowflake_database.this.name}.PUBLIC" } @@ -187,7 +187,7 @@ resource "snowflake_grant_privileges_to_account_role" "public" { # Table grants resource "snowflake_grant_ownership" "tables" { provider = snowflake.securityadmin - account_role_name = snowflake_account_role.this["READWRITECONTROL"].name + account_role_name = snowflake_role.this["READWRITECONTROL"].name on { future { object_type_plural = "TABLES" @@ -200,7 +200,7 @@ resource "snowflake_grant_privileges_to_account_role" "tables" { provider = snowflake.securityadmin for_each = local.table privileges = each.value - account_role_name = snowflake_account_role.this[each.key].name + account_role_name = snowflake_role.this[each.key].name on_schema_object { future { object_type_plural = "TABLES" @@ -213,7 +213,7 @@ resource "snowflake_grant_privileges_to_account_role" "tables" { # View grants resource "snowflake_grant_ownership" "views" { provider = snowflake.securityadmin - account_role_name = snowflake_account_role.this["READWRITECONTROL"].name + account_role_name = snowflake_role.this["READWRITECONTROL"].name on { future { object_type_plural = "VIEWS" @@ -226,7 +226,7 @@ resource "snowflake_grant_privileges_to_account_role" "views" { provider = snowflake.securityadmin for_each = local.view privileges = each.value - account_role_name = snowflake_account_role.this[each.key].name + account_role_name = snowflake_role.this[each.key].name on_schema_object { future { object_type_plural = "VIEWS" diff --git a/terraform/snowflake/modules/elt/roles.tf b/terraform/snowflake/modules/elt/roles.tf index 0bed3047..a84e3929 100644 --- a/terraform/snowflake/modules/elt/roles.tf +++ b/terraform/snowflake/modules/elt/roles.tf @@ -5,7 +5,7 @@ # The loader persona is for tools like Airflow or Fivetran, which load # raw data into Snowflake for later processing. It has read/write/control # permissions in RAW. -resource "snowflake_account_role" "loader" { +resource "snowflake_role" "loader" { provider = snowflake.useradmin name = "LOADER_${var.environment}" comment = "Permissions to load data to the ${module.raw.name} database" @@ -14,7 +14,7 @@ resource "snowflake_account_role" "loader" { # The transformer persona is for in-warehouse data transformations. Most analytics # engineers will use this role, as will dbt robot users. It has read/write/control # permissions in ANALYTICS and TRANSFORM, as well as read permissions in RAW. -resource "snowflake_account_role" "transformer" { +resource "snowflake_role" "transformer" { provider = snowflake.useradmin name = "TRANSFORMER_${var.environment}" comment = "Permissions to read data from the ${module.raw.name} database, and read/write to ${module.transform.name} and ${module.analytics.name}" @@ -22,7 +22,7 @@ resource "snowflake_account_role" "transformer" { # The reporter persona is for BI tools to consume analysis-ready tables in the # analytics databse. It has read permissions in ANALYTICS. -resource "snowflake_account_role" "reporter" { +resource "snowflake_role" "reporter" { provider = snowflake.useradmin name = "REPORTER_${var.environment}" comment = "Permissions to read data from the ${module.analytics.name} database" @@ -30,7 +30,7 @@ resource "snowflake_account_role" "reporter" { # The reader persona is for CI tools to be able to reflect on the databases. # TODO: can we restrict the permissions for this role to just REFERENCES? -resource "snowflake_account_role" "reader" { +resource "snowflake_role" "reader" { provider = snowflake.useradmin name = "READER_${var.environment}" comment = "Permissions to read ${module.analytics.name}, ${module.transform.name}, and ${module.raw.name} for CI purposes" @@ -38,7 +38,7 @@ resource "snowflake_account_role" "reader" { # The logger role is for logging solutions like Sentinel to introspect # things like usage and access. -resource "snowflake_account_role" "logger" { +resource "snowflake_role" "logger" { provider = snowflake.useradmin name = "LOGGER_${var.environment}" comment = "Permissions to read the SNOWFLAKE metadatabase for logging purposes" @@ -54,25 +54,25 @@ resource "snowflake_account_role" "logger" { resource "snowflake_grant_account_role" "loader_to_sysadmin" { provider = snowflake.useradmin - role_name = snowflake_account_role.loader.name + role_name = snowflake_role.loader.name parent_role_name = "SYSADMIN" } resource "snowflake_grant_account_role" "transformer_to_sysadmin" { provider = snowflake.useradmin - role_name = snowflake_account_role.transformer.name + role_name = snowflake_role.transformer.name parent_role_name = "SYSADMIN" } resource "snowflake_grant_account_role" "reporter_to_sysadmin" { provider = snowflake.useradmin - role_name = snowflake_account_role.reporter.name + role_name = snowflake_role.reporter.name parent_role_name = "SYSADMIN" } resource "snowflake_grant_account_role" "reader_to_sysadmin" { provider = snowflake.useradmin - role_name = snowflake_account_role.reader.name + role_name = snowflake_role.reader.name parent_role_name = "SYSADMIN" } @@ -80,7 +80,7 @@ resource "snowflake_grant_account_role" "reader_to_sysadmin" { # directly to accountadmin resource "snowflake_grant_account_role" "logger_to_accountadmin" { provider = snowflake.accountadmin - role_name = snowflake_account_role.logger.name + role_name = snowflake_role.logger.name parent_role_name = "ACCOUNTADMIN" } @@ -88,35 +88,35 @@ resource "snowflake_grant_account_role" "logger_to_accountadmin" { resource "snowflake_grant_account_role" "raw_rwc_to_loader" { provider = snowflake.useradmin role_name = "${module.raw.name}_READWRITECONTROL" - parent_role_name = snowflake_account_role.loader.name + parent_role_name = snowflake_role.loader.name } # Reporter has read privileges in ANALYTICS resource "snowflake_grant_account_role" "analytics_r_to_reporter" { provider = snowflake.useradmin role_name = "${module.analytics.name}_READ" - parent_role_name = snowflake_account_role.reporter.name + parent_role_name = snowflake_role.reporter.name } # Transformer has RWC privileges in TRANSFORM resource "snowflake_grant_account_role" "transform_rwc_to_transformer" { provider = snowflake.useradmin role_name = "${module.transform.name}_READWRITECONTROL" - parent_role_name = snowflake_account_role.transformer.name + parent_role_name = snowflake_role.transformer.name } # Transformer has RWC privileges in ANALYTICS resource "snowflake_grant_account_role" "analytics_rwc_to_transformer" { provider = snowflake.useradmin role_name = "${module.analytics.name}_READWRITECONTROL" - parent_role_name = snowflake_account_role.transformer.name + parent_role_name = snowflake_role.transformer.name } # Transformer has read permissions in RAW resource "snowflake_grant_account_role" "raw_r_to_transformer" { provider = snowflake.useradmin role_name = "${module.raw.name}_READ" - parent_role_name = snowflake_account_role.transformer.name + parent_role_name = snowflake_role.transformer.name } # Transformer can use the TRANSFORMING warehouse @@ -124,7 +124,7 @@ resource "snowflake_grant_account_role" "transforming_to_transformer" { provider = snowflake.useradmin for_each = toset(values(module.transforming)[*].access_role_name) role_name = each.key - parent_role_name = snowflake_account_role.transformer.name + parent_role_name = snowflake_role.transformer.name } # Reporter can use the REPORTING warehouse @@ -132,7 +132,7 @@ resource "snowflake_grant_account_role" "reporting_to_reporter" { provider = snowflake.useradmin for_each = toset(values(module.reporting)[*].access_role_name) role_name = each.key - parent_role_name = snowflake_account_role.reporter.name + parent_role_name = snowflake_role.reporter.name } # Loader can use the LOADING warehouse @@ -140,28 +140,28 @@ resource "snowflake_grant_account_role" "loading_to_loader" { provider = snowflake.useradmin for_each = toset(values(module.loading)[*].access_role_name) role_name = each.key - parent_role_name = snowflake_account_role.loader.name + parent_role_name = snowflake_role.loader.name } # Reader has read permissions in RAW resource "snowflake_grant_account_role" "raw_r_to_reader" { provider = snowflake.useradmin role_name = "${module.raw.name}_READ" - parent_role_name = snowflake_account_role.reader.name + parent_role_name = snowflake_role.reader.name } # Reader has read permissions in TRANSFORM resource "snowflake_grant_account_role" "transform_r_to_reader" { provider = snowflake.useradmin role_name = "${module.transform.name}_READ" - parent_role_name = snowflake_account_role.reader.name + parent_role_name = snowflake_role.reader.name } # Reader has read permissions in ANALYTICS resource "snowflake_grant_account_role" "analytics_r_to_reader" { provider = snowflake.useradmin role_name = "${module.analytics.name}_READ" - parent_role_name = snowflake_account_role.reader.name + parent_role_name = snowflake_role.reader.name } # Reader can use the REPORTING warehouse @@ -169,14 +169,14 @@ resource "snowflake_grant_account_role" "reporting_to_reader" { provider = snowflake.useradmin for_each = toset(values(module.reporting)[*].access_role_name) role_name = each.key - parent_role_name = snowflake_account_role.reader.name + parent_role_name = snowflake_role.reader.name } # Logger can use the LOGGING warehouse resource "snowflake_grant_account_role" "logging_to_logger" { provider = snowflake.useradmin role_name = module.logging.access_role_name - parent_role_name = snowflake_account_role.logger.name + parent_role_name = snowflake_role.logger.name } ###################################### @@ -186,7 +186,7 @@ resource "snowflake_grant_account_role" "logging_to_logger" { # Imported privileges for logging resource "snowflake_grant_privileges_to_account_role" "imported_privileges_to_logger" { provider = snowflake.accountadmin - account_role_name = snowflake_account_role.logger.name + account_role_name = snowflake_role.logger.name privileges = ["IMPORTED PRIVILEGES"] on_account_object { object_type = "DATABASE" diff --git a/terraform/snowflake/modules/elt/users.tf b/terraform/snowflake/modules/elt/users.tf index 986c9453..2976a0f3 100644 --- a/terraform/snowflake/modules/elt/users.tf +++ b/terraform/snowflake/modules/elt/users.tf @@ -8,7 +8,7 @@ resource "snowflake_user" "dbt" { comment = "Service user for dbt Cloud" default_warehouse = module.transforming["XS"].name - default_role = snowflake_account_role.transformer.name + default_role = snowflake_role.transformer.name must_change_password = false } @@ -20,7 +20,7 @@ resource "snowflake_user" "airflow" { comment = "Service user for Airflow" default_warehouse = module.loading["XS"].name - default_role = snowflake_account_role.loader.name + default_role = snowflake_role.loader.name must_change_password = false } @@ -31,7 +31,7 @@ resource "snowflake_user" "fivetran" { comment = "Service user for Fivetran" default_warehouse = module.loading["XS"].name - default_role = snowflake_account_role.loader.name + default_role = snowflake_role.loader.name must_change_password = false } @@ -42,7 +42,7 @@ resource "snowflake_user" "github_ci" { comment = "Service user for GitHub CI" default_warehouse = module.reporting["XS"].name - default_role = snowflake_account_role.reader.name + default_role = snowflake_role.reader.name must_change_password = false } @@ -53,7 +53,7 @@ resource "snowflake_user" "sentinel" { comment = "Service user for Sentinel" default_warehouse = module.logging.name - default_role = snowflake_account_role.logger.name + default_role = snowflake_role.logger.name must_change_password = false } @@ -64,30 +64,30 @@ resource "snowflake_user" "sentinel" { resource "snowflake_grant_account_role" "transformer_to_dbt" { provider = snowflake.useradmin - role_name = snowflake_account_role.transformer.name + role_name = snowflake_role.transformer.name user_name = snowflake_user.dbt.name } resource "snowflake_grant_account_role" "loader_to_airflow" { provider = snowflake.useradmin - role_name = snowflake_account_role.loader.name + role_name = snowflake_role.loader.name user_name = snowflake_user.airflow.name } resource "snowflake_grant_account_role" "loader_to_fivetran" { provider = snowflake.useradmin - role_name = snowflake_account_role.loader.name + role_name = snowflake_role.loader.name user_name = snowflake_user.fivetran.name } resource "snowflake_grant_account_role" "reader_to_github_ci" { provider = snowflake.useradmin - role_name = snowflake_account_role.reader.name + role_name = snowflake_role.reader.name user_name = snowflake_user.github_ci.name } resource "snowflake_grant_account_role" "logger_to_sentinel" { provider = snowflake.useradmin - role_name = snowflake_account_role.logger.name + role_name = snowflake_role.logger.name user_name = snowflake_user.sentinel.name } diff --git a/terraform/snowflake/modules/warehouse/main.tf b/terraform/snowflake/modules/warehouse/main.tf index 30671262..c8b2e909 100644 --- a/terraform/snowflake/modules/warehouse/main.tf +++ b/terraform/snowflake/modules/warehouse/main.tf @@ -50,7 +50,7 @@ resource "snowflake_warehouse" "this" { ################################# # Monitoring, usage, and operating permissions for the LOADING warehouse. -resource "snowflake_account_role" "this" { +resource "snowflake_role" "this" { name = "${var.name}_WH_MOU" provider = snowflake.useradmin comment = "Monitoring, usage, and operating permissions for the ${var.name} warehouse" @@ -62,7 +62,7 @@ resource "snowflake_account_role" "this" { resource "snowflake_grant_account_role" "this_to_sysadmin" { provider = snowflake.useradmin - role_name = snowflake_account_role.this.name + role_name = snowflake_role.this.name parent_role_name = "SYSADMIN" } @@ -73,7 +73,7 @@ resource "snowflake_grant_account_role" "this_to_sysadmin" { resource "snowflake_grant_privileges_to_account_role" "this" { provider = snowflake.securityadmin privileges = local.warehouse.MOU - account_role_name = snowflake_account_role.this.name + account_role_name = snowflake_role.this.name on_account_object { object_type = "WAREHOUSE" object_name = snowflake_warehouse.this.name diff --git a/terraform/snowflake/modules/warehouse/outputs.tf b/terraform/snowflake/modules/warehouse/outputs.tf index a88df60a..4ab74254 100644 --- a/terraform/snowflake/modules/warehouse/outputs.tf +++ b/terraform/snowflake/modules/warehouse/outputs.tf @@ -1,6 +1,6 @@ output "access_role_name" { description = "Warehouse access_role" - value = snowflake_account_role.this.name + value = snowflake_role.this.name } output "name" { From ca78905ed49f4218eb60af2810d790348cde7415 Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Tue, 8 Oct 2024 09:08:42 -0700 Subject: [PATCH 09/11] Bump snowflake provider version. 0.92 is the last version that has the deprecated resources, which is needed to destroy them properly. A follow-up PR will bump the version again., --- .../environments/dev/.terraform.lock.hcl | 30 ++++++++++--------- terraform/snowflake/environments/dev/main.tf | 2 +- .../environments/prd/.terraform.lock.hcl | 30 ++++++++++--------- terraform/snowflake/environments/prd/main.tf | 2 +- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/terraform/snowflake/environments/dev/.terraform.lock.hcl b/terraform/snowflake/environments/dev/.terraform.lock.hcl index 2d587176..038767b1 100644 --- a/terraform/snowflake/environments/dev/.terraform.lock.hcl +++ b/terraform/snowflake/environments/dev/.terraform.lock.hcl @@ -2,21 +2,23 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/snowflake-labs/snowflake" { - version = "0.88.0" - constraints = "0.88.0, ~> 0.88" + version = "0.92.0" + constraints = "~> 0.88, 0.92.0" hashes = [ - "h1:qREluhKI48/JjHy0umPkUX0WDLE6xW/swUyczzG59WA=", - "zh:0c9e1e0596ca77cc03f911bc2d164a72a61ed40ed79956e5624fd6d054eefac9", - "zh:102b210ff3b464aea4992381fc63bd46ac92b38d85c1ce0bdca910604137b81e", - "zh:1182e368736807d4688a1483676917dbfb1400cfba1aa61845e18a9019660b8f", - "zh:12ad9acfaf91351799063c328d560b299a05e015af44d3c7189bfedc731a033a", - "zh:57e349019ecd59b0899bc2f2bd8c5f21d38f4d53ec2e84a659e5e1438e4d30c9", - "zh:8e03b5c2a7d16feb98b3b4c0de6270d14a649e9ccb7bcc13bbeac0960036f68e", - "zh:c7e3c8e45eb64ec3d25760f0f664d449b57c1a3d07c86f198cfb1aa69602464a", - "zh:d297c8338c39b84811cc6c9161da36f1bdd7ab71d9b48e15f37b734b4acd02c0", - "zh:e7bec6a0fd8aed7771898b8d4d3c9fa4e1974da15ae52cff3410ffdbc1e6e245", - "zh:ebd3858e0fabc5d3d8586a6446a29375241e776429af41490753b7171ef6f5f1", + "h1:gEss1CYtwBknBv7k+qjk+dBz7XwGyl7YQi1MDYkYGZg=", + "h1:iZa/QVqOFfxqJwvvJQyExkS1ZW4FDiR+q7JdUkCW3iY=", + "h1:yHFALpBAbt+cJIwR42uuVECmYuWUMChSrGiPejW+ySE=", + "zh:5243cc31b0d761406009a943c713e2148543f982cb0376efc721a5b4dee16802", + "zh:7a79a12ee3022ae8105eb8efee562873bbfa9518acdf2bb572cfef40a107f962", + "zh:7f780ebc8cbaa319ccd0c93cc52cacc0966cb4fc036895ae7c7eeabc7983f275", + "zh:a30c5bb1057cc94948c1c06e361081b310a37a1625a795c3122e286b1ba4ad5d", + "zh:bc826239bffba37743b10abc36350cede21481b434221a1bc49e0cb1828a176d", + "zh:cbbcfd9e5f0fa51d90adf51e70185db3136b0fd558ae0794eccf6884cac111b2", + "zh:d285091bea835c69cc5a1e4689f0cafa95b9b68d85042a52dd49311f8753c078", + "zh:d45b2685e9fecd8b32fb43090b8b7f19541a34addf64468e646a5b6347188d5d", + "zh:d668770a1ecc7e39688816b3aaa551802958bac07c36a67ceab3791d06e2412d", + "zh:dd870eec408f2fc2c8f907ddab3192fc8bde15dc4d205c3587fee68b8636ad7a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - "zh:f952e9bdd890f61d2f33ab15c10641dbcca0fc3735debd9ee5d1562fa3340582", + "zh:f9807dfec6d9ce60b12fe86a5dc1dfdd38a3bf85d8de8df2f5485cd9dde28263", ] } diff --git a/terraform/snowflake/environments/dev/main.tf b/terraform/snowflake/environments/dev/main.tf index abb07814..0bc7b546 100644 --- a/terraform/snowflake/environments/dev/main.tf +++ b/terraform/snowflake/environments/dev/main.tf @@ -20,7 +20,7 @@ terraform { required_providers { snowflake = { source = "Snowflake-Labs/snowflake" - version = "0.88" + version = "0.92" } } required_version = ">= 1.0" diff --git a/terraform/snowflake/environments/prd/.terraform.lock.hcl b/terraform/snowflake/environments/prd/.terraform.lock.hcl index 2d587176..038767b1 100644 --- a/terraform/snowflake/environments/prd/.terraform.lock.hcl +++ b/terraform/snowflake/environments/prd/.terraform.lock.hcl @@ -2,21 +2,23 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/snowflake-labs/snowflake" { - version = "0.88.0" - constraints = "0.88.0, ~> 0.88" + version = "0.92.0" + constraints = "~> 0.88, 0.92.0" hashes = [ - "h1:qREluhKI48/JjHy0umPkUX0WDLE6xW/swUyczzG59WA=", - "zh:0c9e1e0596ca77cc03f911bc2d164a72a61ed40ed79956e5624fd6d054eefac9", - "zh:102b210ff3b464aea4992381fc63bd46ac92b38d85c1ce0bdca910604137b81e", - "zh:1182e368736807d4688a1483676917dbfb1400cfba1aa61845e18a9019660b8f", - "zh:12ad9acfaf91351799063c328d560b299a05e015af44d3c7189bfedc731a033a", - "zh:57e349019ecd59b0899bc2f2bd8c5f21d38f4d53ec2e84a659e5e1438e4d30c9", - "zh:8e03b5c2a7d16feb98b3b4c0de6270d14a649e9ccb7bcc13bbeac0960036f68e", - "zh:c7e3c8e45eb64ec3d25760f0f664d449b57c1a3d07c86f198cfb1aa69602464a", - "zh:d297c8338c39b84811cc6c9161da36f1bdd7ab71d9b48e15f37b734b4acd02c0", - "zh:e7bec6a0fd8aed7771898b8d4d3c9fa4e1974da15ae52cff3410ffdbc1e6e245", - "zh:ebd3858e0fabc5d3d8586a6446a29375241e776429af41490753b7171ef6f5f1", + "h1:gEss1CYtwBknBv7k+qjk+dBz7XwGyl7YQi1MDYkYGZg=", + "h1:iZa/QVqOFfxqJwvvJQyExkS1ZW4FDiR+q7JdUkCW3iY=", + "h1:yHFALpBAbt+cJIwR42uuVECmYuWUMChSrGiPejW+ySE=", + "zh:5243cc31b0d761406009a943c713e2148543f982cb0376efc721a5b4dee16802", + "zh:7a79a12ee3022ae8105eb8efee562873bbfa9518acdf2bb572cfef40a107f962", + "zh:7f780ebc8cbaa319ccd0c93cc52cacc0966cb4fc036895ae7c7eeabc7983f275", + "zh:a30c5bb1057cc94948c1c06e361081b310a37a1625a795c3122e286b1ba4ad5d", + "zh:bc826239bffba37743b10abc36350cede21481b434221a1bc49e0cb1828a176d", + "zh:cbbcfd9e5f0fa51d90adf51e70185db3136b0fd558ae0794eccf6884cac111b2", + "zh:d285091bea835c69cc5a1e4689f0cafa95b9b68d85042a52dd49311f8753c078", + "zh:d45b2685e9fecd8b32fb43090b8b7f19541a34addf64468e646a5b6347188d5d", + "zh:d668770a1ecc7e39688816b3aaa551802958bac07c36a67ceab3791d06e2412d", + "zh:dd870eec408f2fc2c8f907ddab3192fc8bde15dc4d205c3587fee68b8636ad7a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - "zh:f952e9bdd890f61d2f33ab15c10641dbcca0fc3735debd9ee5d1562fa3340582", + "zh:f9807dfec6d9ce60b12fe86a5dc1dfdd38a3bf85d8de8df2f5485cd9dde28263", ] } diff --git a/terraform/snowflake/environments/prd/main.tf b/terraform/snowflake/environments/prd/main.tf index abb07814..0bc7b546 100644 --- a/terraform/snowflake/environments/prd/main.tf +++ b/terraform/snowflake/environments/prd/main.tf @@ -20,7 +20,7 @@ terraform { required_providers { snowflake = { source = "Snowflake-Labs/snowflake" - version = "0.88" + version = "0.92" } } required_version = ">= 1.0" From 504f5d5f5421d5ed29e60c2aab2586a940cf1a3d Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Tue, 8 Oct 2024 09:13:43 -0700 Subject: [PATCH 10/11] Turn back on prevent_destroy --- terraform/snowflake/modules/database/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/snowflake/modules/database/main.tf b/terraform/snowflake/modules/database/main.tf index 03bb7ccb..fa4bf19a 100644 --- a/terraform/snowflake/modules/database/main.tf +++ b/terraform/snowflake/modules/database/main.tf @@ -97,7 +97,7 @@ resource "snowflake_database" "this" { data_retention_time_in_days = var.data_retention_time_in_days lifecycle { - prevent_destroy = false + prevent_destroy = true } } From 408d9c94bca69333717411def6d8cc359a3120ff Mon Sep 17 00:00:00 2001 From: Ian Rose Date: Tue, 8 Oct 2024 09:14:34 -0700 Subject: [PATCH 11/11] Remove TODO --- terraform/snowflake/modules/database/main.tf | 2 -- 1 file changed, 2 deletions(-) diff --git a/terraform/snowflake/modules/database/main.tf b/terraform/snowflake/modules/database/main.tf index fa4bf19a..c458b884 100644 --- a/terraform/snowflake/modules/database/main.tf +++ b/terraform/snowflake/modules/database/main.tf @@ -135,8 +135,6 @@ resource "snowflake_grant_account_role" "this_to_sysadmin" { # roles created here also get the same permissions in newly-created schemas and tables. # https://community.snowflake.com/s/article/How-to-grant-select-on-all-future-tables-in-a-schema-and-database-level -# TODO: ownership grants on all and future tables - # Database grants resource "snowflake_grant_privileges_to_account_role" "database" { provider = snowflake.securityadmin