Skip to content

Commit

Permalink
chore: Remove hardcoded values from documentation (#3381)
Browse files Browse the repository at this point in the history
<!-- Feel free to delete comments as you fill this in -->
- Discourage using hardcoded values by removing them from the examples
in resources and the provider. Use TF variables instead.
<!-- summary of changes -->
  • Loading branch information
sfc-gh-jmichalak authored Feb 10, 2025
1 parent 9be2196 commit cb1d6e2
Show file tree
Hide file tree
Showing 29 changed files with 519 additions and 131 deletions.
76 changes: 59 additions & 17 deletions docs/guides/authentication_methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,23 @@ provider "snowflake" {
organization_name = "<organization_name>"
account_name = "<account_name>"
user = "<user_name>"
password = "<password>"
password = var.password
}
variable "password" {
type = string
sensitive = true
}
```

You can then set Terraform variables like:
- If a variable does not have any value set, you will be prompted by Terraform to provide the value.
- Use Terraform VAR environment variables: `TF_VAR_password="<key>" terraform plan`
- Use Terraform flags: `terraform plan -var="private_key=<key>"`
- Use Snowflake Terraform Provider flags: `SNOWFLAKE_PRIVATE_KEY="<key>" terraform plan`

Remember to load `<key>` from a secure location, instead of hardcoding the value.

Without passing any authenticator, we depend on the underlying Go Snowflake driver and Snowflake itself to fill this field out.
This means that we do not provision the default, and it may change at some point, so if you want to be explicit, you can define Snowflake authenticator like so:

Expand All @@ -61,12 +74,17 @@ provider "snowflake" {
organization_name = "<organization_name>"
account_name = "<account_name>"
user = "<user_name>"
password = "<password>"
password = var.password
authenticator = "Snowflake"
}
variable "password" {
type = string
sensitive = true
}
```

### JWT authenticator flow
### JWT authenticator flow

To use JWT authentication, you have to firstly generate key-pairs used by Snowflake.
To correctly generate the necessary keys, follow [this guide](https://docs.snowflake.com/en/user-guide/key-pair-auth#configuring-key-pair-authentication) from the official Snowflake documentation.
Expand All @@ -78,28 +96,32 @@ provider "snowflake" {
organization_name = "<organization_name>"
account_name = "<account_name>"
user = "<user_name>"
authenticator = "JWT"
authenticator = "SNOWFLAKE_JWT"
private_key = file("~/.ssh/snowflake_private_key.p8")
# Optionally, set it with Terraform variable.
private_key = var.private_key
}
variable "private_key" {
type = string
sensitive = true
}
```

To load the private key you can utilize the built-in [file](https://developer.hashicorp.com/terraform/language/functions/file) function.
If you have any issues with this method, one of the possible root causes could be an additional newline at the end of the file that causes error in the underlying Go Snowflake driver.
If this doesn't help, you can try other methods of supplying this field:
- Filling the key directly by using [multi-string notation](https://developer.hashicorp.com/terraform/language/expressions/strings#heredoc-strings)
- Filling the key directly by using [multi-string notation](https://developer.hashicorp.com/terraform/language/expressions/strings#heredoc-strings) (not recommended).
- Sourcing it from the environment variable:
```shell
export SNOWFLAKE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----..."
# Alternatively, source from a file.
export SNOWFLAKE_PRIVATE_KEY=$(cat ~/.ssh/snowflake_private_key.p8)

export SNOWFLAKE_PRIVATE_KEY_PASSPHRASE="..."
# Or inline the value (not recommended).
export SNOWFLAKE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----..."
```
- Using TOML configuration file:
```toml
[default]
private_key = "..."
private_key_passphrase = "..."
```

In case of any other issues, take a look at related topics:
Expand All @@ -115,9 +137,14 @@ provider "snowflake" {
organization_name = "<organization_name>"
account_name = "<account_name>"
user = "<user_name>"
authenticator = "JWT"
authenticator = "SNOWFLAKE_JWT"
private_key = file("~/.ssh/snowflake_private_key.p8")
private_key_passphrase = "<passphrase>"
private_key_passphrase = var.private_key_passphrase
}
variable "private_key_passphrase" {
type = string
sensitive = true
}
```

Expand All @@ -134,9 +161,14 @@ provider "snowflake" {
organization_name = "<organization_name>"
account_name = "<account_name>"
user = "<user_name>"
password = "<password>"
password = var.password
authenticator = "UsernamePasswordMFA"
}
variable "password" {
type = string
sensitive = true
}
```

and the configuration that uses passcode:
Expand All @@ -146,10 +178,15 @@ provider "snowflake" {
organization_name = "<organization_name>"
account_name = "<account_name>"
user = "<user_name>"
password = "<password>"
password = var.password
authenticator = "UsernamePasswordMFA"
passcode = "000000"
}
variable "password" {
type = string
sensitive = true
}
```

#### MFA token caching
Expand All @@ -168,10 +205,15 @@ provider "snowflake" {
organization_name = "<organization_name>"
account_name = "<account_name>"
user = "<user_name>"
password = "<password>"
password = var.password
authenticator = "Okta"
okta_url = "https://dev-123456.okta.com"
}
variable "password" {
type = string
sensitive = true
}
```

## Common issues
Expand All @@ -196,7 +238,7 @@ The output of this command is your `<account_name>`.

### Be sure you are passing all the required fields

This point is not only referring to double-checking the fields you are passing, but also to inform you that depending on the account
This point is not only referring to double-checking the fields you are passing, but also to inform you that depending on the account
you want to log into, a different set of parameters may be required.

Whenever you are on a Snowflake deployment that has different url than the default one:
Expand All @@ -206,4 +248,4 @@ Whenever you are on a Snowflake deployment that has different url than the defau
open snowflake connection: 261004 (08004): failed to auth for unknown reason.
```

This error can be raised for a number of reasons, but explicitly specifying the host has effectively prevented such occurrences so far.
This error can be raised for a number of reasons, but explicitly specifying the host has effectively prevented such occurrences so far.
16 changes: 11 additions & 5 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,14 @@ provider "snowflake" {
account_name = "..." # required if not using profile. Can also be set via SNOWFLAKE_ACCOUNT_NAME env var
user = "..." # required if not using profile or token. Can also be set via SNOWFLAKE_USER env var
authenticator = "SNOWFLAKE_JWT"
private_key = "-----BEGIN ENCRYPTED PRIVATE KEY-----..."
private_key_passphrase = "passphrase"
private_key = file("~/.ssh/snowflake_key.p8")
private_key_passphrase = var.private_key_passphrase
}
# Remember to provide the passphrase securely.
variable "private_key_passphrase" {
type = string
sensitive = true
}
# By using the `profile` field, missing fields will be populated from ~/.snowflake/config TOML file
Expand Down Expand Up @@ -135,6 +141,8 @@ The Snowflake provider support multiple ways to authenticate:

In all cases `organization_name`, `account_name` and `user` are required.

-> **Note** Storing the credentials and other secret values safely is on the users' side. Read more in [Authentication Methods guide](./guides/authentication_methods).

### Keypair Authentication Environment Variables

You should generate the public and private keys and set up environment variables.
Expand All @@ -150,8 +158,6 @@ To export the variables into your provider:

```shell
export SNOWFLAKE_USER="..."
export SNOWFLAKE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----..."
# Alternatively, source from a file.
export SNOWFLAKE_PRIVATE_KEY=$(cat ~/.ssh/snowflake_key.p8)
```

Expand Down Expand Up @@ -233,7 +239,7 @@ provider "snowflake" {

```bash
export SNOWFLAKE_USER="..."
export SNOWFLAKE_PRIVATE_KEY="~/.ssh/snowflake_key"
export SNOWFLAKE_PRIVATE_KEY=$(cat ~/.ssh/snowflake_key.p8)
```

3. In a TOML file (default in ~/.snowflake/config). Notice the use of different profiles. The profile name needs to be specified in the Terraform configuration file in `profile` field. When this is not specified, `default` profile is loaded.
Expand Down
45 changes: 35 additions & 10 deletions docs/resources/account.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ The account resource allows you to create and manage Snowflake accounts. For mor
## Minimal
resource "snowflake_account" "minimal" {
name = "ACCOUNT_NAME"
admin_name = "ADMIN_NAME"
admin_password = "ADMIN_PASSWORD"
email = "admin@email.com"
admin_name = var.admin_name
admin_password = var.admin_password
email = var.email
edition = "STANDARD"
grace_period_in_days = 3
}
## Complete (with SERVICE user type)
resource "snowflake_account" "complete" {
name = "ACCOUNT_NAME"
admin_name = "ADMIN_NAME"
admin_name = var.admin_name
admin_rsa_public_key = "<public_key>"
admin_user_type = "SERVICE"
email = "admin@email.com"
email = var.email
edition = "STANDARD"
region_group = "PUBLIC"
region = "AWS_US_WEST_2"
Expand All @@ -44,12 +44,12 @@ resource "snowflake_account" "complete" {
## Complete (with PERSON user type)
resource "snowflake_account" "complete" {
name = "ACCOUNT_NAME"
admin_name = "ADMIN_NAME"
admin_password = "ADMIN_PASSWORD"
admin_name = var.admin_name
admin_password = var.admin_password
admin_user_type = "PERSON"
first_name = "first_name"
last_name = "last_name"
email = "admin@email.com"
first_name = var.first_name
last_name = var.last_name
email = var.email
must_change_password = "false"
edition = "STANDARD"
region_group = "PUBLIC"
Expand All @@ -58,6 +58,31 @@ resource "snowflake_account" "complete" {
is_org_admin = "true"
grace_period_in_days = 3
}
variable "admin_name" {
type = string
sensitive = true
}
variable "email" {
type = string
sensitive = true
}
variable "admin_password" {
type = string
sensitive = true
}
variable "first_name" {
type = string
sensitive = true
}
variable "last_name" {
type = string
sensitive = true
}
```
-> **Note** Instead of using fully_qualified_name, you can reference objects managed outside Terraform by constructing a correct ID, consult [identifiers guide](../guides/identifiers_rework_design_decisions#new-computed-fully-qualified-name-field-in-resources).
<!-- TODO(SNOW-1634854): include an example showing both methods-->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ Resource used to manage api authentication security integration objects with aut
resource "snowflake_api_authentication_integration_with_authorization_code_grant" "test" {
enabled = true
name = "test"
oauth_client_id = "sn-oauth-134o9erqfedlc"
oauth_client_secret = "eb9vaXsrcEvrFdfcvCaoijhilj4fc"
oauth_client_id = var.oauth_client_id
oauth_client_secret = var.oauth_client_secret
}
# resource with all fields set
resource "snowflake_api_authentication_integration_with_authorization_code_grant" "test" {
Expand All @@ -30,11 +30,21 @@ resource "snowflake_api_authentication_integration_with_authorization_code_grant
oauth_allowed_scopes = ["useraccount"]
oauth_authorization_endpoint = "https://example.com"
oauth_client_auth_method = "CLIENT_SECRET_POST"
oauth_client_id = "sn-oauth-134o9erqfedlc"
oauth_client_secret = "eb9vaXsrcEvrFdfcvCaoijhilj4fc"
oauth_client_id = var.oauth_client_id
oauth_client_secret = var.oauth_client_secret
oauth_refresh_token_validity = 42
oauth_token_endpoint = "https://example.com"
}
variable "oauth_client_id" {
type = string
sensitive = true
}
variable "oauth_client_secret" {
type = string
sensitive = true
}
```
-> **Note** Instead of using fully_qualified_name, you can reference objects managed outside Terraform by constructing a correct ID, consult [identifiers guide](../guides/identifiers_rework_design_decisions#new-computed-fully-qualified-name-field-in-resources).
<!-- TODO(SNOW-1634854): include an example showing both methods-->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ Resource used to manage api authentication security integration objects with cli
resource "snowflake_api_authentication_integration_with_client_credentials" "test" {
enabled = true
name = "test"
oauth_client_id = "sn-oauth-134o9erqfedlc"
oauth_client_secret = "eb9vaXsrcEvrFdfcvCaoijhilj4fc"
oauth_client_id = var.oauth_client_id
oauth_client_secret = var.oauth_client_secret
}
# resource with all fields set
resource "snowflake_api_authentication_integration_with_client_credentials" "test" {
Expand All @@ -29,10 +29,20 @@ resource "snowflake_api_authentication_integration_with_client_credentials" "tes
oauth_access_token_validity = 42
oauth_allowed_scopes = ["useraccount"]
oauth_client_auth_method = "CLIENT_SECRET_POST"
oauth_client_id = "sn-oauth-134o9erqfedlc"
oauth_client_secret = "eb9vaXsrcEvrFdfcvCaoijhilj4fc"
oauth_client_id = var.oauth_client_id
oauth_client_secret = var.oauth_client_secret
oauth_token_endpoint = "https://example.com"
}
variable "oauth_client_id" {
type = string
sensitive = true
}
variable "oauth_client_secret" {
type = string
sensitive = true
}
```
-> **Note** Instead of using fully_qualified_name, you can reference objects managed outside Terraform by constructing a correct ID, consult [identifiers guide](../guides/identifiers_rework_design_decisions#new-computed-fully-qualified-name-field-in-resources).
<!-- TODO(SNOW-1634854): include an example showing both methods-->
Expand Down
18 changes: 14 additions & 4 deletions docs/resources/api_authentication_integration_with_jwt_bearer.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ Resource used to manage api authentication security integration objects with jwt
resource "snowflake_api_authentication_integration_with_jwt_bearer" "test" {
enabled = true
name = "test"
oauth_client_id = "sn-oauth-134o9erqfedlc"
oauth_client_secret = "eb9vaXsrcEvrFdfcvCaoijhilj4fc"
oauth_client_id = var.oauth_client_id
oauth_client_secret = var.oauth_client_secret
oauth_assertion_issuer = "issuer"
}
# resource with all fields set
Expand All @@ -30,12 +30,22 @@ resource "snowflake_api_authentication_integration_with_jwt_bearer" "test" {
oauth_access_token_validity = 42
oauth_authorization_endpoint = "https://example.com"
oauth_client_auth_method = "CLIENT_SECRET_POST"
oauth_client_id = "sn-oauth-134o9erqfedlc"
oauth_client_secret = "eb9vaXsrcEvrFdfcvCaoijhilj4fc"
oauth_client_id = var.oauth_client_id
oauth_client_secret = var.oauth_client_secret
oauth_refresh_token_validity = 42
oauth_token_endpoint = "https://example.com"
oauth_assertion_issuer = "issuer"
}
variable "oauth_client_id" {
type = string
sensitive = true
}
variable "oauth_client_secret" {
type = string
sensitive = true
}
```
-> **Note** Instead of using fully_qualified_name, you can reference objects managed outside Terraform by constructing a correct ID, consult [identifiers guide](../guides/identifiers_rework_design_decisions#new-computed-fully-qualified-name-field-in-resources).
<!-- TODO(SNOW-1634854): include an example showing both methods-->
Expand Down
Loading

0 comments on commit cb1d6e2

Please sign in to comment.