From 460bab45f9fe1a52d32d4d355a87e617c6bfa532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Mon, 10 Jun 2024 07:43:16 +0200 Subject: [PATCH] Resolve merge conflicts and adjust docs for databases --- docs/data-sources/databases.md | 8 ++-- docs/resources/secondary_database.md | 35 +++++++++++++++- docs/resources/shared_database.md | 11 ++++- docs/resources/standard_database.md | 41 ++++++++++++++++--- .../snowflake_databases/data-source.tf | 6 +-- .../snowflake_secondary_database/resource.tf | 32 ++++++++++++++- .../snowflake_shared_database/resource.tf | 11 ++++- .../snowflake_standard_database/resource.tf | 35 +++++++++++++++- pkg/datasources/databases.go | 2 +- .../TestAcc_Databases/optionals_set/test.tf | 2 +- .../TestAcc_Databases/optionals_unset/test.tf | 2 +- pkg/helpers/helpers_test.go | 3 +- pkg/provider/provider.go | 4 +- .../TestAcc_SharedDatabase/complete/test.tf | 6 +-- .../resources/secondary_database.md.tmpl | 33 +++++++++++++++ 15 files changed, 203 insertions(+), 28 deletions(-) create mode 100644 templates/resources/secondary_database.md.tmpl diff --git a/docs/data-sources/databases.md b/docs/data-sources/databases.md index c05a35f15b2..47097a56a01 100644 --- a/docs/data-sources/databases.md +++ b/docs/data-sources/databases.md @@ -52,10 +52,10 @@ output "limit_output" { # Without additional data (to limit the number of calls make for every found database) data "snowflake_databases" "only_show" { - # with_describe is turned on by default and it calls DESCRIBE DATABASE for every database found and attaches it's output to databases.*.description field + # with_describe is turned on by default and it calls DESCRIBE DATABASE for every database found and attaches its output to databases.*.description field with_describe = false - # with_parameters is turned on by default and it calls SHOW PARAMETERS FOR DATABASE for every database found and attaches it's output to databases.*.parameters field + # with_parameters is turned on by default and it calls SHOW PARAMETERS FOR DATABASE for every database found and attaches its output to databases.*.parameters field with_parameters = false } @@ -74,7 +74,7 @@ data "snowflake_databases" "assert_with_postcondition" { } } -# Ensure the number of databases is equal to at exatly one element (with the use of check block) +# Ensure the number of databases is equal to at exactly one element (with the use of check block) check "database_check" { data "snowflake_databases" "assert_with_check_block" { like = "database-name" @@ -93,7 +93,7 @@ check "database_check" { ### Optional - `like` (String) Filters the output with **case-insensitive** pattern, with support for SQL wildcard characters (`%` and `_`). -- `limit` (Block List, Max: 1) Limits the number of rows returned. The limit may start from the first element matched by from which is optional. (see [below for nested schema](#nestedblock--limit)) +- `limit` (Block List, Max: 1) Limits the number of rows returned. If the `limit.from` is set, then the limit wll start from the first element matched by the expression. The expression is only used to match with the first element, later on the elements are not matched by the prefix, but you can enforce a certain pattern with `starts_with` or `like`. (see [below for nested schema](#nestedblock--limit)) - `starts_with` (String) Filters the output with **case-sensitive** characters indicating the beginning of the object name. - `with_describe` (Boolean) Runs DESC DATABASE for each database returned by SHOW DATABASES. The output of describe is saved to the description field. By default this value is set to true. - `with_parameters` (Boolean) Runs SHOW PARAMETERS FOR DATABASE for each database returned by SHOW DATABASES. The output of describe is saved to the parameters field as a map. By default this value is set to true. diff --git a/docs/resources/secondary_database.md b/docs/resources/secondary_database.md index 6961617d106..ad6b11170b6 100644 --- a/docs/resources/secondary_database.md +++ b/docs/resources/secondary_database.md @@ -1,4 +1,5 @@ --- +# generated by https://github.com/hashicorp/terraform-plugin-docs page_title: "snowflake_secondary_database Resource - terraform-provider-snowflake" subcategory: "" description: |- @@ -7,6 +8,8 @@ description: |- # snowflake_secondary_database (Resource) +~> **Note** The snowflake_secondary_database resource doesn't refresh itself, as the best practice is to use tasks scheduled for a certain interval. Check out the examples to see how to set up the refresh task. For SQL-based replication guide, see the [official documentation](https://docs.snowflake.com/en/user-guide/db-replication-config#replicating-a-database-to-another-account). + A secondary database creates a replica of an existing primary database (i.e. a secondary database). For more information about database replication, see [Introduction to database replication across multiple accounts](https://docs.snowflake.com/en/user-guide/db-replication-intro). ## Example Usage @@ -17,7 +20,7 @@ resource "snowflake_standard_database" "primary" { provider = primary_account # notice the provider fields name = "database_name" replication { - enable_for_account { + enable_to_account { account_identifier = "." with_failover = true } @@ -26,6 +29,14 @@ resource "snowflake_standard_database" "primary" { } # 2. Creating secondary database +## 2.1. Minimal version +resource "snowflake_secondary_database" "test" { + provider = secondary_account + name = snowflake_standard_database.primary.name # It's recommended to give a secondary database the same name as its primary database + as_replica_of = "..${snowflake_standard_database.primary.name}" +} + +## 2.2. Complete version (with every optional set) resource "snowflake_secondary_database" "test" { provider = secondary_account name = snowflake_standard_database.primary.name # It's recommended to give a secondary database the same name as its primary database @@ -36,7 +47,7 @@ resource "snowflake_secondary_database" "test" { data_retention_time_in_days = 10 max_data_extension_time_in_days = 20 external_volume = "" - catalog = "" + catalog = "" replace_invalid_characters = false default_ddl_collation = "en_US" storage_serialization_policy = "COMPATIBLE" @@ -50,6 +61,26 @@ resource "snowflake_secondary_database" "test" { quoted_identifiers_ignore_case = false enable_console_output = false } + +# The snowflake_secondary_database resource doesn't refresh itself, as the best practice is to use tasks scheduled for a certain interval. +# To create the refresh tasks, use separate database and schema. + +resource "snowflake_standard_database" "tasks" { + name = "database_for_tasks" +} + +resource "snowflake_schema" "tasks" { + name = "schema_for_tasks" + database = snowflake_standard_database.tasks.name +} + +resource "snowflake_task" "refresh_secondary_database" { + database = snowflake_standard_database.tasks.name + name = "refresh_secondary_database" + schema = snowflake_schema.tasks.name + schedule = "10 minute" + sql_statement = "ALTER DATABASE ${snowflake_secondary_database.test.name} REFRESH" +} ``` diff --git a/docs/resources/shared_database.md b/docs/resources/shared_database.md index f5d68a7915c..17e5cca2991 100644 --- a/docs/resources/shared_database.md +++ b/docs/resources/shared_database.md @@ -32,6 +32,15 @@ resource "snowflake_grant_privileges_to_share" "test" { } # 2. Creating shared database +## 2.1. Minimal version +resource "snowflake_shared_database" "test" { + provider = secondary_account + depends_on = [snowflake_grant_privileges_to_share.test] + name = snowflake_standard_database.test.name # shared database should have the same as the "imported" one + from_share = "..${snowflake_share.test.name}" +} + +## 2.2. Complete version (with every optional set) resource "snowflake_shared_database" "test" { provider = secondary_account depends_on = [snowflake_grant_privileges_to_share.test] @@ -43,7 +52,7 @@ resource "snowflake_shared_database" "test" { data_retention_time_in_days = 10 max_data_extension_time_in_days = 20 external_volume = "" - catalog = "" + catalog = "" replace_invalid_characters = false default_ddl_collation = "en_US" storage_serialization_policy = "COMPATIBLE" diff --git a/docs/resources/standard_database.md b/docs/resources/standard_database.md index eb7e255a655..a6d00e4493e 100644 --- a/docs/resources/standard_database.md +++ b/docs/resources/standard_database.md @@ -12,15 +12,22 @@ Represents a standard database. If replication configuration is specified, the d ## Example Usage ```terraform +## Minimal +resource "snowflake_standard_database" "primary" { + name = "database_name" +} + +## Complete (with every optional set) resource "snowflake_standard_database" "primary" { name = "database_name" is_transient = false comment = "my standard database" data_retention_time_in_days = 10 + data_retention_time_in_days_save = 10 max_data_extension_time_in_days = 20 external_volume = "" - catalog = "" + catalog = "" replace_invalid_characters = false default_ddl_collation = "en_US" storage_serialization_policy = "COMPATIBLE" @@ -35,13 +42,37 @@ resource "snowflake_standard_database" "primary" { enable_console_output = false replication { - enable_for_account { + enable_to_account { account_identifier = "." with_failover = true } ignore_edition_check = true } } + +## Replication with for_each +locals { + replication_configs = [ + { + account_identifier = "." + with_failover = true + }, + { + account_identifier = "." + with_failover = true + }, + ] +} + +resource "snowflake_standard_database" "primary" { + name = "database_name" + for_each = local.replication_configs + + replication { + enable_to_account = each.value + ignore_edition_check = true + } +} ``` @@ -82,14 +113,14 @@ resource "snowflake_standard_database" "primary" { Required: -- `enable_for_account` (Block List, Min: 1) Entry to enable replication and optionally failover for a given account identifier. (see [below for nested schema](#nestedblock--replication--enable_for_account)) +- `enable_to_account` (Block List, Min: 1) Entry to enable replication and optionally failover for a given account identifier. (see [below for nested schema](#nestedblock--replication--enable_to_account)) Optional: - `ignore_edition_check` (Boolean) Allows replicating data to accounts on lower editions in either of the following scenarios: 1. The primary database is in a Business Critical (or higher) account but one or more of the accounts approved for replication are on lower editions. Business Critical Edition is intended for Snowflake accounts with extremely sensitive data. 2. The primary database is in a Business Critical (or higher) account and a signed business associate agreement is in place to store PHI data in the account per HIPAA and HITRUST regulations, but no such agreement is in place for one or more of the accounts approved for replication, regardless if they are Business Critical (or higher) accounts. Both scenarios are prohibited by default in an effort to help prevent account administrators for Business Critical (or higher) accounts from inadvertently replicating sensitive data to accounts on lower editions. - -### Nested Schema for `replication.enable_for_account` + +### Nested Schema for `replication.enable_to_account` Required: diff --git a/examples/data-sources/snowflake_databases/data-source.tf b/examples/data-sources/snowflake_databases/data-source.tf index d7169949761..f6f21658df5 100644 --- a/examples/data-sources/snowflake_databases/data-source.tf +++ b/examples/data-sources/snowflake_databases/data-source.tf @@ -38,10 +38,10 @@ output "limit_output" { # Without additional data (to limit the number of calls make for every found database) data "snowflake_databases" "only_show" { - # with_describe is turned on by default and it calls DESCRIBE DATABASE for every database found and attaches it's output to databases.*.description field + # with_describe is turned on by default and it calls DESCRIBE DATABASE for every database found and attaches its output to databases.*.description field with_describe = false - # with_parameters is turned on by default and it calls SHOW PARAMETERS FOR DATABASE for every database found and attaches it's output to databases.*.parameters field + # with_parameters is turned on by default and it calls SHOW PARAMETERS FOR DATABASE for every database found and attaches its output to databases.*.parameters field with_parameters = false } @@ -60,7 +60,7 @@ data "snowflake_databases" "assert_with_postcondition" { } } -# Ensure the number of databases is equal to at exatly one element (with the use of check block) +# Ensure the number of databases is equal to at exactly one element (with the use of check block) check "database_check" { data "snowflake_databases" "assert_with_check_block" { like = "database-name" diff --git a/examples/resources/snowflake_secondary_database/resource.tf b/examples/resources/snowflake_secondary_database/resource.tf index b2f7fbaa4f9..c1bef8306c7 100644 --- a/examples/resources/snowflake_secondary_database/resource.tf +++ b/examples/resources/snowflake_secondary_database/resource.tf @@ -3,7 +3,7 @@ resource "snowflake_standard_database" "primary" { provider = primary_account # notice the provider fields name = "database_name" replication { - enable_for_account { + enable_to_account { account_identifier = "." with_failover = true } @@ -12,6 +12,14 @@ resource "snowflake_standard_database" "primary" { } # 2. Creating secondary database +## 2.1. Minimal version +resource "snowflake_secondary_database" "test" { + provider = secondary_account + name = snowflake_standard_database.primary.name # It's recommended to give a secondary database the same name as its primary database + as_replica_of = "..${snowflake_standard_database.primary.name}" +} + +## 2.2. Complete version (with every optional set) resource "snowflake_secondary_database" "test" { provider = secondary_account name = snowflake_standard_database.primary.name # It's recommended to give a secondary database the same name as its primary database @@ -22,7 +30,7 @@ resource "snowflake_secondary_database" "test" { data_retention_time_in_days = 10 max_data_extension_time_in_days = 20 external_volume = "" - catalog = "" + catalog = "" replace_invalid_characters = false default_ddl_collation = "en_US" storage_serialization_policy = "COMPATIBLE" @@ -36,3 +44,23 @@ resource "snowflake_secondary_database" "test" { quoted_identifiers_ignore_case = false enable_console_output = false } + +# The snowflake_secondary_database resource doesn't refresh itself, as the best practice is to use tasks scheduled for a certain interval. +# To create the refresh tasks, use separate database and schema. + +resource "snowflake_standard_database" "tasks" { + name = "database_for_tasks" +} + +resource "snowflake_schema" "tasks" { + name = "schema_for_tasks" + database = snowflake_standard_database.tasks.name +} + +resource "snowflake_task" "refresh_secondary_database" { + database = snowflake_standard_database.tasks.name + name = "refresh_secondary_database" + schema = snowflake_schema.tasks.name + schedule = "10 minute" + sql_statement = "ALTER DATABASE ${snowflake_secondary_database.test.name} REFRESH" +} diff --git a/examples/resources/snowflake_shared_database/resource.tf b/examples/resources/snowflake_shared_database/resource.tf index 3ab7129d44f..8e8e6161153 100644 --- a/examples/resources/snowflake_shared_database/resource.tf +++ b/examples/resources/snowflake_shared_database/resource.tf @@ -18,6 +18,15 @@ resource "snowflake_grant_privileges_to_share" "test" { } # 2. Creating shared database +## 2.1. Minimal version +resource "snowflake_shared_database" "test" { + provider = secondary_account + depends_on = [snowflake_grant_privileges_to_share.test] + name = snowflake_standard_database.test.name # shared database should have the same as the "imported" one + from_share = "..${snowflake_share.test.name}" +} + +## 2.2. Complete version (with every optional set) resource "snowflake_shared_database" "test" { provider = secondary_account depends_on = [snowflake_grant_privileges_to_share.test] @@ -29,7 +38,7 @@ resource "snowflake_shared_database" "test" { data_retention_time_in_days = 10 max_data_extension_time_in_days = 20 external_volume = "" - catalog = "" + catalog = "" replace_invalid_characters = false default_ddl_collation = "en_US" storage_serialization_policy = "COMPATIBLE" diff --git a/examples/resources/snowflake_standard_database/resource.tf b/examples/resources/snowflake_standard_database/resource.tf index 5e3c1d31d60..2c1d039ee2b 100644 --- a/examples/resources/snowflake_standard_database/resource.tf +++ b/examples/resources/snowflake_standard_database/resource.tf @@ -1,12 +1,19 @@ +## Minimal +resource "snowflake_standard_database" "primary" { + name = "database_name" +} + +## Complete (with every optional set) resource "snowflake_standard_database" "primary" { name = "database_name" is_transient = false comment = "my standard database" data_retention_time_in_days = 10 + data_retention_time_in_days_save = 10 max_data_extension_time_in_days = 20 external_volume = "" - catalog = "" + catalog = "" replace_invalid_characters = false default_ddl_collation = "en_US" storage_serialization_policy = "COMPATIBLE" @@ -21,10 +28,34 @@ resource "snowflake_standard_database" "primary" { enable_console_output = false replication { - enable_for_account { + enable_to_account { account_identifier = "." with_failover = true } ignore_edition_check = true } } + +## Replication with for_each +locals { + replication_configs = [ + { + account_identifier = "." + with_failover = true + }, + { + account_identifier = "." + with_failover = true + }, + ] +} + +resource "snowflake_standard_database" "primary" { + name = "database_name" + for_each = local.replication_configs + + replication { + enable_to_account = each.value + ignore_edition_check = true + } +} diff --git a/pkg/datasources/databases.go b/pkg/datasources/databases.go index ef84f90efab..c8ddae417a3 100644 --- a/pkg/datasources/databases.go +++ b/pkg/datasources/databases.go @@ -36,7 +36,7 @@ var databasesSchema = map[string]*schema.Schema{ "limit": { Type: schema.TypeList, Optional: true, - Description: `Limits the number of rows returned. The limit may start from the first element matched by from which is optional.`, + Description: "Limits the number of rows returned. If the `limit.from` is set, then the limit wll start from the first element matched by the expression. The expression is only used to match with the first element, later on the elements are not matched by the prefix, but you can enforce a certain pattern with `starts_with` or `like`.", MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ diff --git a/pkg/datasources/testdata/TestAcc_Databases/optionals_set/test.tf b/pkg/datasources/testdata/TestAcc_Databases/optionals_set/test.tf index 0a9942691a1..9f2f1e4c6ff 100644 --- a/pkg/datasources/testdata/TestAcc_Databases/optionals_set/test.tf +++ b/pkg/datasources/testdata/TestAcc_Databases/optionals_set/test.tf @@ -2,7 +2,7 @@ resource "snowflake_standard_database" "test" { name = var.name comment = var.comment replication { - enable_for_account { + enable_to_account { account_identifier = var.account_identifier with_failover = true } diff --git a/pkg/datasources/testdata/TestAcc_Databases/optionals_unset/test.tf b/pkg/datasources/testdata/TestAcc_Databases/optionals_unset/test.tf index 13948471997..7230f51b3d0 100644 --- a/pkg/datasources/testdata/TestAcc_Databases/optionals_unset/test.tf +++ b/pkg/datasources/testdata/TestAcc_Databases/optionals_unset/test.tf @@ -2,7 +2,7 @@ resource "snowflake_standard_database" "test" { name = var.name comment = var.comment replication { - enable_for_account { + enable_to_account { account_identifier = var.account_identifier with_failover = true } diff --git a/pkg/helpers/helpers_test.go b/pkg/helpers/helpers_test.go index 03c5ae465f3..f0a3f9a5a87 100644 --- a/pkg/helpers/helpers_test.go +++ b/pkg/helpers/helpers_test.go @@ -2,9 +2,10 @@ package helpers import ( "fmt" - "github.com/stretchr/testify/assert" "testing" + "github.com/stretchr/testify/assert" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/stretchr/testify/require" ) diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index fc406e27263..f2d7e745c3f 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -457,7 +457,6 @@ func getResources() map[string]*schema.Resource { "snowflake_alert": resources.Alert(), "snowflake_api_integration": resources.APIIntegration(), "snowflake_database": resources.Database(), - "snowflake_standard_database": resources.StandardDatabase(), "snowflake_database_role": resources.DatabaseRole(), "snowflake_dynamic_table": resources.DynamicTable(), "snowflake_email_notification_integration": resources.EmailNotificationIntegration(), @@ -495,9 +494,12 @@ func getResources() map[string]*schema.Resource { "snowflake_saml_integration": resources.SAMLIntegration(), "snowflake_schema": resources.Schema(), "snowflake_scim_integration": resources.SCIMIntegration(), + "snowflake_secondary_database": resources.SecondaryDatabase(), "snowflake_sequence": resources.Sequence(), "snowflake_session_parameter": resources.SessionParameter(), "snowflake_share": resources.Share(), + "snowflake_shared_database": resources.SharedDatabase(), + "snowflake_standard_database": resources.StandardDatabase(), "snowflake_stage": resources.Stage(), "snowflake_storage_integration": resources.StorageIntegration(), "snowflake_stream": resources.Stream(), diff --git a/pkg/resources/testdata/TestAcc_SharedDatabase/complete/test.tf b/pkg/resources/testdata/TestAcc_SharedDatabase/complete/test.tf index c51c870e384..417d31a68da 100644 --- a/pkg/resources/testdata/TestAcc_SharedDatabase/complete/test.tf +++ b/pkg/resources/testdata/TestAcc_SharedDatabase/complete/test.tf @@ -1,7 +1,7 @@ resource "snowflake_shared_database" "test" { - name = var.name - from_share = var.from_share - comment = var.comment + name = var.name + from_share = var.from_share + comment = var.comment external_volume = var.external_volume catalog = var.catalog diff --git a/templates/resources/secondary_database.md.tmpl b/templates/resources/secondary_database.md.tmpl new file mode 100644 index 00000000000..2fb8f72c98b --- /dev/null +++ b/templates/resources/secondary_database.md.tmpl @@ -0,0 +1,33 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "" +description: |- +{{ if gt (len (split .Description "")) 1 -}} +{{ index (split .Description "") 1 | plainmarkdown | trimspace | prefixlines " " }} +{{- else -}} +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +{{- end }} +--- + +# {{.Name}} ({{.Type}}) + +~> **Note** The snowflake_secondary_database resource doesn't refresh itself, as the best practice is to use tasks scheduled for a certain interval. Check out the examples to see how to set up the refresh task. For SQL-based replication guide, see the [official documentation](https://docs.snowflake.com/en/user-guide/db-replication-config#replicating-a-database-to-another-account). + +{{ .Description | trimspace }} + +{{ if .HasExample -}} +## Example Usage + +{{ tffile (printf "examples/resources/%s/resource.tf" .Name)}} +{{- end }} + +{{ .SchemaMarkdown | trimspace }} +{{- if .HasImport }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" (printf "examples/resources/%s/import.sh" .Name)}} +{{- end }}