This document is meant to help you migrate your Terraform config to the new newest version. In migration guides, we will only describe deprecations or breaking changes and help you to change your configuration to keep the same (or similar) behavior across different versions.
While solving issue #2733 we have introduced diff suppression for column.type
. To make it work correctly we have also added a validation to it. It should not cause any problems, but it's worth noting in case of any data types used that the provider is not aware of.
Diff suppression for arguments.type
is needed for the same reason as above for snowflake_table
resource.
Now the tag_masking_policy_association
resource will only accept fully qualified names separated by dot .
instead of pipe |
.
Before
resource "snowflake_tag_masking_policy_association" "name" {
tag_id = snowflake_tag.this.id
masking_policy_id = snowflake_masking_policy.example_masking_policy.id
}
After
resource "snowflake_tag_masking_policy_association" "name" {
tag_id = "\"${snowflake_tag.this.database}\".\"${snowflake_tag.this.schema}\".\"${snowflake_tag.this.name}\""
masking_policy_id = "\"${snowflake_masking_policy.example_masking_policy.database}\".\"${snowflake_masking_policy.example_masking_policy.schema}\".\"${snowflake_masking_policy.example_masking_policy.name}\""
}
It's more verbose now, but after identifier rework it should be similar to the previous form.
The ForceNew
field was removed in favor of in-place Update for name
parameter in:
snowflake_file_format
snowflake_masking_policy
So from now, these objects won't be re-created when thename
changes, but instead only the name will be updated withALTER .. RENAME TO
statements.
From now on, the snowflake_procedure
's execute_as
parameter allows only two values: OWNER and CALLER (case-insensitive). Setting other values earlier resulted in falling back to the Snowflake default (currently OWNER) and creating a permadiff.
snowflake_grants
datasource was refreshed as part of the ongoing Grants Redesign.
To be aligned with the convention in other grant resources, role
was renamed to account_role
for the following fields:
grants_to.role
grants_of.role
future_grants_to.role
.
To migrate simply change role
to account_role
in the aforementioned fields.
grants_to.share
was a text field. Because Snowflake introduced new syntax SHOW GRANTS TO SHARE <share_name> IN APPLICATION PACKAGE <app_package_name>
(check more in the docs) the type was changed to object. To migrate simply change:
data "snowflake_grants" "example_to_share" {
grants_to {
share = "some_share"
}
}
to
data "snowflake_grants" "example_to_share" {
grants_to {
share {
share_name = "some_share"
}
}
}
Note: in_application_package
is not yet supported.
future_grants_in.schema
was an object field allowing to set required schema_name
and optional database_name
. Our strategy is to be explicit, so the schema field was changed to string and fully qualified name is expected. To migrate change:
data "snowflake_grants" "example_future_in_schema" {
future_grants_in {
schema {
database_name = "some_database"
schema_name = "some_schema"
}
}
}
to
data "snowflake_grants" "example_future_in_schema" {
future_grants_in {
schema = "\"some_database\".\"some_schema\""
}
}
grants_to
was enriched with three new options:
application
application_role
database_role
No migration work is needed here.
grants_to
was enriched with two new options:
database_role
application_role
No migration work is needed here.
future_grants_to
was enriched with one new option:
database_role
No migration work is needed here.
Descriptions of attributes were altered. More examples were added (both for old and new features).
Previously, in snowflake_database
when creating a database form share, it was possible to provide from_share.provider
in the format of <org_name>.<account_name>
. It worked even though we expected account locator because our "external" identifier wasn't quoting its string representation.
To be consistent with other identifier types, we quoted the output of "external" identifiers which makes such configurations break
(previously, they were working "by accident"). To fix it, the previous format of <org_name>.<account_name>
has to be changed
to account locator format <account_locator>
(mind that it's now case-sensitive). The account locator can be retrieved by calling select current_account();
on the sharing account.
In the future we would like to eventually come back to the <org_name>.<account_name>
format as it's recommended by Snowflake.
There were several issues reported about the configuration hierarchy, e.g. #2294 and #2242. In fact, the order of precedence described in the docs was not followed. This have led to the incorrect behavior.
After migrating to this version, the hierarchy from the docs should be followed:
The Snowflake provider will use the following order of precedence when determining which credentials to use:
1) Provider Configuration
2) Environment Variables
3) Config File
BEWARE: your configurations will be affected with that change because they may have been leveraging the incorrect configurations precedence. Please be sure to check all the configurations before running terraform.
Longer context in #2517.
After this change, one apply may be required to update the state correctly for failover group resources using ACCOUNT PARAMETERS
.
(behavior change) Database data_retention_time_in_days
+ Schema data_retention_days
+ Table data_retention_time_in_days
For context #2356.
To make data retention fields truly optional (previously they were producing plan every time when no value was set),
we added -1
as a possible value, and it is set as default. That got rid of the unexpected plans when no value is set and added possibility to use default value assigned by Snowflake (see the data retention period).
For context #2356.
To define data retention days for table data_retention_time_in_days
should be used as deprecated data_retention_days
field is being removed.
The type
of the constraint was limited back to UNIQUE
, PRIMARY KEY
, and FOREIGN KEY
.
The reason for that is, that syntax for Out-of-Line constraint (docs) does not contain NOT NULL
.
It is noted as a behavior change but in some way it is not; with the previous implementation it did not work at all with type
set to NOT NULL
because the generated statement was not a valid Snowflake statement.
We will consider adding NOT NULL
back because it can be set by ALTER COLUMN columnX SET NOT NULL
, but first we want to revisit the whole resource design.
The docs were inconsistent. Example prior to 0.86.0 version showed using the table.id
as the table_id
reference. The description of the table_id
parameter never allowed such a value (table.id
is a |
-delimited identifier representation and only the .
-separated values were listed in the docs: https://registry.terraform.io/providers/Snowflake-Labs/snowflake/0.85.0/docs/resources/table_constraint#required. The misuse of table.id
parameter will result in error after migrating to 0.86.0. To make the config work, please remove and reimport the constraint resource from the state as described in resource migration doc.
After discussions in #2535 we decided to provide a temporary workaround in 0.87.0 version, so that the manual migration is not necessary. It allows skipping the migration and jumping straight to 0.87.0 version. However, the temporary workaround will be gone in one of the future versions. Please adjust to the newly suggested reference with the new resources you create.
The return_null_allowed
attribute default value is now true
. This is a behavior change because it was false
before. The reason it was changed is to match the expected default value in the documentation Default: The default is NULL (i.e. the function can return NULL values).
The comment
attribute is now optional. It was required before, but it is not required in Snowflake API.
The schema
attribute is now required with database
attribute to match old implementation SHOW EXTERNAL FUNCTIONS IN SCHEMA "<database>"."<schema>"
. In the future this may change to make schema optional.
In recent changes, we introduced a new grant resources to replace the old ones. To aid with the migration, we wrote a guide to show one of the possible ways to migrate deprecated resources to their new counter-parts. As the guide is more general and applies to every version (and provider), we moved it here.
return_behavior
parameter is deprecated because it is also deprecated in the Snowflake API.
return_type
has become force new because there is no way to alter it without dropping and recreating the function.
Setting copy_options
to ON_ERROR = 'CONTINUE'
would result in a permadiff. Use ON_ERROR = CONTINUE
(without single quotes) or bump to v0.89.0 in which the behavior was fixed.
notification_provider
becomes required and has three possible values AZURE_STORAGE_QUEUE
, AWS_SNS
, and GCP_PUBSUB
.
It is still possible to set it to AWS_SQS
but because there is no underlying SQL, so it will result in an error.
Attributes aws_sqs_arn
and aws_sqs_role_arn
will be ignored.
Computed attributes aws_sqs_external_id
and aws_sqs_iam_user_arn
won't be updated.
Force new was added for the following attributes (because no usable SQL alter statements for them):
azure_storage_queue_primary_uri
azure_tenant_id
gcp_pubsub_subscription_name
gcp_pubsub_topic_name
direction
parameter is deprecated because it is added automatically on the SDK level.
type
parameter is deprecated because it is added automatically on the SDK level (and basically it's always QUEUE
).
In this change we have done a provider refactor to make it more complete and customizable by supporting more options that were already available in Golang Snowflake driver. This lead to several attributes being added and a few deprecated. We will focus on the deprecated ones and show you how to adapt your current configuration to the new changes.
provider "snowflake" {
# before
username = "username"
# after
user = "username"
}
provider "snowflake" {
# before
browser_auth = false
oauth_access_token = "<access_token>"
oauth_refresh_token = "<refresh_token>"
oauth_client_id = "<client_id>"
oauth_client_secret = "<client_secret>"
oauth_endpoint = "<endpoint>"
oauth_redirect_url = "<redirect_uri>"
# after
authenticator = "ExternalBrowser"
token = "<access_token>"
token_accessor {
refresh_token = "<refresh_token>"
client_id = "<client_id>"
client_secret = "<client_secret>"
token_endpoint = "<endpoint>"
redirect_uri = "<redirect_uri>"
}
}
Specifying a region is a legacy thing and according to https://docs.snowflake.com/en/user-guide/admin-account-identifier you can specify a region as a part of account parameter. Specifying account parameter with the region is also considered legacy, but with this approach it will be easier to convert only your account identifier to the new preferred way of specifying account identifier.
provider "snowflake" {
# before
region = "<cloud_region_id>"
# after
account = "<account_locator>.<cloud_region_id>"
}
provider "snowflake" {
# before
private_key_path = "<filepath>"
# after
private_key = file("<filepath>")
}
provider "snowflake" {
# before
session_params = {}
# after
params = {}
}
Before the change authenticator
parameter did not have to be set for private key authentication and was deduced by the provider. The change is a result of the introduced configuration alignment with an underlying gosnowflake driver. The authentication type is required there, and it defaults to user+password one. From this version, set authenticator
to JWT
explicitly.