Skip to content

Commit 2a60f21

Browse files
Merge pull request #4708 from snowflakedb/dev
chore: Merge dev to main before v2.16.0
2 parents a03e96b + bf6d255 commit 2a60f21

421 files changed

Lines changed: 20147 additions & 7948 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/ISSUE_TEMPLATE/01-bug.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ body:
134134
- resource:api_authn_integration_jwt_bearer
135135
- resource:api_integration
136136
- resource:authentication_policy
137+
- resource:catalog_integration
137138
- resource:compute_pool
138139
- resource:cortex_search_service
139140
- resource:current_account
@@ -202,6 +203,7 @@ body:
202203
- resource:secret_with_generic_string
203204
- resource:sequence
204205
- resource:session_parameter
206+
- resource:session_policy
205207
- resource:service
206208
- resource:service_user
207209
- resource:share
@@ -227,12 +229,14 @@ body:
227229
- resource:user_password_policy_attachment
228230
- resource:user_programmatic_access_token
229231
- resource:user_public_keys
232+
- resource:user_session_policy_attachment
230233
- resource:view
231234
- resource:warehouse
232235

233236
- data_source:accounts
234237
- data_source:account_roles
235238
- data_source:alerts
239+
- data_source:catalog_integrations
236240
- data_source:compute_pools
237241
- data_source:connections
238242
- data_source:cortex_search_services

.github/ISSUE_TEMPLATE/02-general-usage.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ body:
132132
- resource:api_authn_integration_jwt_bearer
133133
- resource:api_integration
134134
- resource:authentication_policy
135+
- resource:catalog_integration
135136
- resource:compute_pool
136137
- resource:cortex_search_service
137138
- resource:current_account
@@ -200,6 +201,7 @@ body:
200201
- resource:secret_with_generic_string
201202
- resource:sequence
202203
- resource:session_parameter
204+
- resource:session_policy
203205
- resource:service
204206
- resource:service_user
205207
- resource:share
@@ -225,12 +227,14 @@ body:
225227
- resource:user_password_policy_attachment
226228
- resource:user_programmatic_access_token
227229
- resource:user_public_keys
230+
- resource:user_session_policy_attachment
228231
- resource:view
229232
- resource:warehouse
230233

231234
- data_source:accounts
232235
- data_source:account_roles
233236
- data_source:alerts
237+
- data_source:catalog_integrations
234238
- data_source:compute_pools
235239
- data_source:connections
236240
- data_source:cortex_search_services

.github/ISSUE_TEMPLATE/03-documentation.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ body:
4242
- resource:api_authn_integration_jwt_bearer
4343
- resource:api_integration
4444
- resource:authentication_policy
45+
- resource:catalog_integration
4546
- resource:compute_pool
4647
- resource:cortex_search_service
4748
- resource:current_account
@@ -110,6 +111,7 @@ body:
110111
- resource:secret_with_generic_string
111112
- resource:sequence
112113
- resource:session_parameter
114+
- resource:session_policy
113115
- resource:service
114116
- resource:service_user
115117
- resource:share
@@ -135,12 +137,14 @@ body:
135137
- resource:user_password_policy_attachment
136138
- resource:user_programmatic_access_token
137139
- resource:user_public_keys
140+
- resource:user_session_policy_attachment
138141
- resource:view
139142
- resource:warehouse
140143

141144
- data_source:accounts
142145
- data_source:account_roles
143146
- data_source:alerts
147+
- data_source:catalog_integrations
144148
- data_source:compute_pools
145149
- data_source:connections
146150
- data_source:cortex_search_services

.github/ISSUE_TEMPLATE/04-feature-request.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ body:
9393
- resource:api_authn_integration_jwt_bearer
9494
- resource:api_integration
9595
- resource:authentication_policy
96+
- resource:catalog_integration
9697
- resource:compute_pool
9798
- resource:cortex_search_service
9899
- resource:current_account
@@ -161,6 +162,7 @@ body:
161162
- resource:secret_with_generic_string
162163
- resource:sequence
163164
- resource:session_parameter
165+
- resource:session_policy
164166
- resource:service
165167
- resource:service_user
166168
- resource:share
@@ -186,12 +188,14 @@ body:
186188
- resource:user_password_policy_attachment
187189
- resource:user_programmatic_access_token
188190
- resource:user_public_keys
191+
- resource:user_session_policy_attachment
189192
- resource:view
190193
- resource:warehouse
191194

192195
- data_source:accounts
193196
- data_source:account_roles
194197
- data_source:alerts
198+
- data_source:catalog_integrations
195199
- data_source:compute_pools
196200
- data_source:connections
197201
- data_source:cortex_search_services

.github/workflows/tests-account-level.yml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,19 @@ jobs:
165165
body: |
166166
Account-level tests ${{ job.status }} for [${{ github.event.client_payload.slash_command.args.named.sha || github.event.pull_request.head.sha }}](https://github.com/snowflakedb/terraform-provider-snowflake/actions/runs/${{ github.run_id }})
167167
168+
# For fork PRs, tests run via repository_dispatch (triggered by /ok-to-test),
169+
# but the resulting check runs are tied to the default branch, not the fork PR.
170+
# This step updates the (skipped) check run on the fork PR's head SHA so the
171+
# PR status reflects the actual test outcome. It resolves the job's display name
172+
# via job.check_run_id (since github.job returns the job_id, not the display name)
173+
# and uses it to find the matching check run on the fork PR's commit.
168174
- name: Set fork job status
169175
uses: actions/github-script@v6
170176
if: ${{ always() }}
171177
id: update_check_run
172178
env:
173179
number: ${{ github.event.client_payload.pull_request.number }}
174-
job: ${{ github.job }}
180+
check_run_id: ${{ job.check_run_id }}
175181
# Conveniently, job.status maps to https://developer.github.com/v3/checks/runs/#update-a-check-run
176182
conclusion: ${{ job.status }}
177183
sha: ${{ github.event.client_payload.slash_command.args.named.sha }}
@@ -183,13 +189,23 @@ jobs:
183189
console.log("Not repository_dispatch... nothing to do!");
184190
return process.env.event_name;
185191
}
192+
const { data: currentCheck } = await github.rest.checks.get({
193+
...context.repo,
194+
check_run_id: parseInt(process.env.check_run_id)
195+
});
196+
const jobName = currentCheck.name;
197+
console.log(`Current job check run name: ${jobName}`);
186198
const ref = process.env.sha;
187199
const { data: checks } = await github.rest.checks.listForRef({
188200
...context.repo,
189201
ref
190202
});
191-
const check = checks.check_runs.filter(c => c.name === process.env.job);
203+
const check = checks.check_runs.filter(c => c.name === jobName);
192204
console.log(check);
205+
if (check.length === 0) {
206+
console.log(`No matching check run found for "${jobName}" on ${ref}`);
207+
return;
208+
}
193209
const { data: result } = await github.rest.checks.update({
194210
...context.repo,
195211
check_run_id: check[0].id,

.github/workflows/tests.yml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,19 @@ jobs:
178178
body: |
179179
Integration tests ${{ job.status }} for [${{ github.event.client_payload.slash_command.args.named.sha || github.event.pull_request.head.sha }}](https://github.com/snowflakedb/terraform-provider-snowflake/actions/runs/${{ github.run_id }})
180180
181+
# For fork PRs, tests run via repository_dispatch (triggered by /ok-to-test),
182+
# but the resulting check runs are tied to the default branch, not the fork PR.
183+
# This step updates the (skipped) check run on the fork PR's head SHA so the
184+
# PR status reflects the actual test outcome. It resolves the job's display name
185+
# via job.check_run_id (since github.job returns the job_id, not the display name)
186+
# and uses it to find the matching check run on the fork PR's commit.
181187
- name: Set fork job status
182188
uses: actions/github-script@v6
183189
if: ${{ always() }}
184190
id: update_check_run
185191
env:
186192
number: ${{ github.event.client_payload.pull_request.number }}
187-
job: ${{ github.job }}
193+
check_run_id: ${{ job.check_run_id }}
188194
# Conveniently, job.status maps to https://developer.github.com/v3/checks/runs/#update-a-check-run
189195
conclusion: ${{ job.status }}
190196
sha: ${{ github.event.client_payload.slash_command.args.named.sha }}
@@ -196,13 +202,23 @@ jobs:
196202
console.log("Not repository_dispatch... nothing to do!");
197203
return process.env.event_name;
198204
}
205+
const { data: currentCheck } = await github.rest.checks.get({
206+
...context.repo,
207+
check_run_id: parseInt(process.env.check_run_id)
208+
});
209+
const jobName = currentCheck.name;
210+
console.log(`Current job check run name: ${jobName}`);
199211
const ref = process.env.sha;
200212
const { data: checks } = await github.rest.checks.listForRef({
201213
...context.repo,
202214
ref
203215
});
204-
const check = checks.check_runs.filter(c => c.name === process.env.job);
216+
const check = checks.check_runs.filter(c => c.name === jobName);
205217
console.log(check);
218+
if (check.length === 0) {
219+
console.log(`No matching check run found for "${jobName}" on ${ref}`);
220+
return;
221+
}
206222
const { data: result } = await github.rest.checks.update({
207223
...context.repo,
208224
check_run_id: check[0].id,

MIGRATION_GUIDE.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,120 @@ for changes required after enabling given [Snowflake BCR Bundle](https://docs.sn
2424
> [!TIP]
2525
> If you're still using the `Snowflake-Labs/snowflake` source, see [Upgrading from Snowflake-Labs Provider](./SNOWFLAKEDB_MIGRATION.md) to upgrade to the snowflakedb namespace.
2626
27+
## v2.15.x ➞ v2.16.0
28+
29+
### *(improvement)* snowflake_password_policy resource rework
30+
31+
The [snowflake_password_policy](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/password_policy) resource has been reworked to follow the modern resource patterns used in this provider.
32+
33+
#### New computed attributes
34+
35+
The resource now exposes `show_output` and `describe_output` computed attributes that provide the raw results from Snowflake's `SHOW PASSWORD POLICIES` and `DESCRIBE PASSWORD POLICY` commands, respectively. This allows users to access all server-side values without needing additional data sources.
36+
37+
#### Integer fields no longer have hardcoded defaults
38+
39+
Previously, all integer fields (`min_length`, `max_length`, etc.) had hardcoded `Default` values in the schema. These have been removed in favor of Snowflake-managed defaults. When a field is not specified in the Terraform configuration, the resource will not send that parameter to Snowflake, allowing it to use its own default value.
40+
41+
Fields where 0 is a valid value (`min_upper_case_chars`, `min_lower_case_chars`, `min_numeric_chars`, `min_special_chars`, `min_age_days`, `max_age_days`, `history`) now use `-1` as the default sentinel. Setting one of these fields to `-1` explicitly (or omitting it from config) means "use the Snowflake default".
42+
43+
Fields where 0 is not a valid value (`min_length`, `max_length`, `max_retries`, `lockout_time_mins`) are now plain optional fields with no default. Omitting them means "use the Snowflake default".
44+
45+
After importing the state, the plan may be not empty for the fields missing from the configuration due to this change. You can either apply the plan, or set the specific values in the configuration.
46+
47+
#### Removed client-side validation
48+
49+
Client-side `ValidateFunc` constraints (e.g., `IntBetween(8, 256)` for `min_length`) have been removed from all integer fields. Validation is now delegated to Snowflake, which will return an error if a value is out of range. This avoids drift between the provider's hardcoded ranges and Snowflake's actual limits.
50+
51+
#### `or_replace` and `if_not_exists` fields deprecated
52+
53+
The `or_replace` and `if_not_exists` fields are now deprecated as noops. They will be removed in a future version.
54+
55+
#### ID format change
56+
57+
During [identifiers rework](https://github.com/snowflakedb/terraform-provider-snowflake/blob/main/ROADMAP.md#identifiers-rework) the internal resource ID format has changed from pipe-separated (`database|schema|name`) to fully qualified name format (`"database"."schema"."name"`). This is handled automatically by a state upgrader — no manual action is required. Read more in the [design decisions](./docs/guides/identifiers_rework_design_decisions.md).
58+
59+
#### Identifier fields now support quoting
60+
61+
The `database`, `schema`, and `name` fields now support quoted identifiers and suppress diffs caused by identifier quoting differences (read more in the [design decisions](./docs/guides/identifiers_rework_design_decisions.md)). Additionally, certain characters are blocklisted from these fields — see the resource documentation for details.
62+
63+
#### Import behavior
64+
65+
The import now uses `ImportName` for `SchemaObjectIdentifier`, which properly sets `database`, `schema`, and `name` fields. The import ID should be the fully qualified name of the password policy (e.g., `"my_database"."my_schema"."my_policy"`).
66+
67+
### *(new feature)* snowflake_password_policies data source
68+
69+
We have added a new preview data source for password policies: [snowflake_password_policies](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/data-sources/password_policies). It supports filtering with `like`, `in`, and `limit`, and optionally runs `DESCRIBE PASSWORD POLICY` for each result (controlled by the `with_describe` attribute, enabled by default).
70+
71+
This feature will be marked as stable in future releases. To use it, add `snowflake_password_policies_datasource` to the `preview_features_enabled` field in the provider configuration.
72+
73+
### *(improvement)* Catalog integration resources: computed `catalog_source`
74+
75+
A new **computed** attribute **`catalog_source`** is now available on these resources:
76+
77+
- [snowflake_catalog_integration_aws_glue](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/catalog_integration_aws_glue)
78+
- [snowflake_catalog_integration_object_storage](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/catalog_integration_object_storage)
79+
- [snowflake_catalog_integration_open_catalog](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/catalog_integration_open_catalog)
80+
- [snowflake_catalog_integration_iceberg_rest](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/catalog_integration_iceberg_rest)
81+
82+
It reflects the active catalog source type Snowflake reports for the integration (for example `GLUE`, `OBJECT_STORE`, `POLARIS`, or `ICEBERG_REST`). The attribute is used to detect when the catalog source was changed outside of Terraform and to recreate the resource when that happens.
83+
84+
No configuration changes are required.
85+
86+
### *(new feature)* New session policy resources and data source
87+
88+
#### Resources
89+
90+
We have added new preview resources for session policies: [snowflake_session_policy](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/session_policy) for defining policies, [snowflake_user_session_policy_attachment](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/user_session_policy_attachment) for assigning a session policy to a user, and [snowflake_account_session_policy_attachment](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/account_session_policy_attachment) for assigning a session policy to the current account.
91+
92+
These features will be marked as stable in future releases. To use them, add the corresponding value to the `preview_features_enabled` field in the provider configuration:
93+
94+
- `snowflake_session_policy_resource` for `snowflake_session_policy`;
95+
- `snowflake_user_session_policy_attachment_resource` for `snowflake_user_session_policy_attachment`;
96+
- `snowflake_account_session_policy_attachment_resource` for `snowflake_account_session_policy_attachment`.
97+
98+
#### Data source
99+
100+
We have added a new preview data source for session policies: [snowflake_session_policies](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/data-sources/session_policies).
101+
102+
This feature will be marked as stable in future releases. To use it, add `snowflake_session_policies_datasource` to the `preview_features_enabled` field in the provider configuration.
103+
104+
No changes are required for existing configurations unless you want to adopt any of these preview features with Terraform.
105+
106+
## v2.15.x ➞ v2.15.1
107+
108+
### *(bug fix)* `snowflake_stream_on_table` and `snowflake_stream_on_view` import fix
109+
110+
Previously, importing `snowflake_stream_on_table` or `snowflake_stream_on_view` with `terraform import` left the `show_initial_rows` attribute as `null` in state, because it cannot be read from Snowflake. On the next `terraform apply`, Terraform detected a diff and produced an "Update" plan. Because of it, the stream was recreated (see the [note](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/stream_on_table)).
111+
112+
To fix this, enable the `IMPORT_BOOLEAN_DEFAULT` experimental feature in the provider configuration and reimport the affected stream resources. When enabled, the `show_initial_rows` attribute is set to `"default"` during import, preventing the permadiff.
113+
114+
References: [#3896](https://github.com/snowflakedb/terraform-provider-snowflake/issues/3896)
115+
116+
### *(bugfix)* TABLE data type parsing with parametrized column types
117+
118+
In v2.15.0, resources that accept a `TABLE(...)` data type (e.g. return type in `snowflake_function_sql` or `snowflake_procedure_sql`)
119+
failed with an error when column types inside the `TABLE` definition carried precision or scale parameters (e.g. `NUMBER(38,0)`, `VARCHAR(256)`).
120+
The comma inside the type parameter was incorrectly treated as a column separator, producing a parse error similar to:
121+
122+
```
123+
number NUMBER(38 could not be parsed, use "NUMBER(precision, scale)" format
124+
```
125+
126+
This release fixes the parser to correctly handle nested parentheses when splitting column definitions,
127+
so `TABLE(ARG1 NUMBER(38,0), ARG2 VARCHAR)` is now parsed correctly.
128+
129+
No configuration changes are required.
130+
131+
### *(bug fix)* Improve handling of granting PUBLIC role
132+
133+
A new experiment `GRANT_ACCOUNT_ROLE_SAFE_PUBLIC_ROLE` is now available for the `snowflake_grant_account_role` resource. When enabled, granting the PUBLIC role is treated as a silent no-op instead of producing an inconsistent-result error.
134+
135+
Snowflake implicitly grants PUBLIC to every role and user, so `GRANT ROLE PUBLIC` is always a no-op at the SQL level and `SHOW GRANTS` never lists it. Without this experiment, the provider's Read clears the state because it cannot find the grant, resulting in `Root object was present, but now absent` errors.
136+
137+
To enable, add `GRANT_ACCOUNT_ROLE_SAFE_PUBLIC_ROLE` to the `experimental_features_enabled` field in the provider configuration. No changes are required for existing configurations that do not grant the PUBLIC role.
138+
139+
References: [#3001](https://github.com/snowflakedb/terraform-provider-snowflake/issues/3001)
140+
27141
## v2.14.x ➞ v2.15.0
28142

29143
### **IMPORTANT** *(improvement)* Go driver bumped to v2

0 commit comments

Comments
 (0)