https://github.com/getindata/terraform-snowflake-user
Terraform module for creating snowflake users
https://github.com/getindata/terraform-snowflake-user
Last synced: 4 months ago
JSON representation
Terraform module for creating snowflake users
- Host: GitHub
- URL: https://github.com/getindata/terraform-snowflake-user
- Owner: getindata
- License: apache-2.0
- Created: 2023-01-11T08:48:53.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-08-20T12:01:34.000Z (10 months ago)
- Last Synced: 2026-02-12T07:12:21.348Z (4 months ago)
- Language: HCL
- Size: 140 KB
- Stars: 3
- Watchers: 5
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# Snowflake User Terraform Module




We help companies turn their data into assets
Terraform module for creating Snowflake user.
This module can:
- Create and manage Snowflake Users
- Automatically generate RSA private and public keys for the User
- Automatically grant `default_role` and `default_secondary_roles` to the User
## Usage
```terraform
module "terraform_snowflake_user" {
source = "getindata/terraform-snowflake/user"
name = "snowflake-user"
}
```
## EXAMPLES
- [Simple](examples/simple) - Basic usage of the module
- [Complete](examples/complete) - Advanced usage of the module
## Breaking changes in v2.x of the module
Due to breaking changes in Snowflake provider and additional code optimizations, **breaking changes** were introduced in `v2.0.0` version of this module.
List of code and variable (API) changes:
- Support for Snowflake user types, managed by `type` variable
- Clear differentiation of `PERSON`, `SERVICE` and `LEGACY_SERVICE` users
- `snowflake_default_secondary_roles` changed to `snowflake_default_secondary_roles_option` (string)
- Added `middle_name`, `query_tag`, `timezone`, `network_policy`, `trace_level`, `log_level` and `enable_unredacted_query_syntax_error` variables
- Added `disable_mfa` flag (`false` by default), that handles MFA enforcement for `PERSON` users
When upgrading from `v1.x`, expect most of the resources to be recreated - if recreation is impossible, then it is possible to import some existing resources.
For more information, refer to [variables.tf](variables.tf), list of inputs below and Snowflake provider documentation
## Breaking changes in v3.x of the module
Due to replacement of nulllabel (`context.tf`) with context provider, some **breaking changes** were introduced in `v3.0.0` version of this module.
List od code and variable (API) changes:
- Removed `context.tf` file (a single-file module with additonal variables), which implied a removal of all its variables (except `name`):
- `descriptor_formats`
- `label_value_case`
- `label_key_case`
- `id_length_limit`
- `regex_replace_chars`
- `label_order`
- `additional_tag_map`
- `tags`
- `labels_as_tags`
- `attributes`
- `delimiter`
- `stage`
- `environment`
- `tenant`
- `namespace`
- `enabled`
- `context`
- Remove support `enabled` flag - that might cause some backward compatibility issues with terraform state (please take into account that proper `move` clauses were added to minimize the impact), but proceed with caution
- Additional `context` provider configuration
- New variables were added, to allow naming configuration via `context` provider:
- `context_templates`
- `name_schema`
## Breaking changes in v4.x of the module
- Due to rename of Snowflake terraform provider source, all `versions.tf` files were updated accordingly.
Please keep in mind to mirror this change in your own repos also.
For more information about provider rename, refer to [Snowflake documentation](https://github.com/snowflakedb/terraform-provider-snowflake/blob/main/SNOWFLAKEDB_MIGRATION.md).
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| [comment](#input\_comment) | Comment / description of Snowflake user | `string` | `null` | no |
| [context\_templates](#input\_context\_templates) | Map of context templates used for naming conventions - this variable supersedes `naming_scheme.properties` and `naming_scheme.delimiter` configuration | `map(string)` | `{}` | no |
| [default\_namespace](#input\_default\_namespace) | Specifies the namespace (database only or database and schema) that is active by default for the user's session upon login. | `string` | `null` | no |
| [default\_role](#input\_default\_role) | Specifies the role that is active by default for the user's session upon login. | `string` | `null` | no |
| [default\_secondary\_roles\_option](#input\_default\_secondary\_roles\_option) | Specifies the secondary roles that are active for the user’s session upon login.
Valid values are (case-insensitive): DEFAULT \| NONE \| ALL | `string` | `"DEFAULT"` | no |
| [default\_warehouse](#input\_default\_warehouse) | Specifies the virtual warehouse that is active by default for the user's session upon login. | `string` | `null` | no |
| [disable\_mfa](#input\_disable\_mfa) | Disable Multi-Factor Authentication for the user (works only with `type = PERSON`) | `bool` | `false` | no |
| [disabled](#input\_disabled) | Specifies whether the user is disabled, which prevents logging in and aborts all the currently-running queries for the user. | `bool` | `false` | no |
| [display\_name](#input\_display\_name) | Name displayed for the user in the Snowflake web interface. | `string` | `null` | no |
| [email](#input\_email) | Email address for the user | `string` | `null` | no |
| [enable\_unredacted\_query\_syntax\_error](#input\_enable\_unredacted\_query\_syntax\_error) | Controls whether query text is redacted if a SQL query fails due to a syntax or parsing error. If FALSE, the content of a failed query is redacted in the views, pages, and functions that provide a query history.
Only users with a role that is granted or inherits the AUDIT privilege can set the ENABLE\_UNREDACTED\_QUERY\_SYNTAX\_ERROR parameter.
When using the ALTER USER command to set the parameter to TRUE for a particular user, modify the user that you want to see the query text, not the user who executed the query (if those are different users). | `bool` | `null` | no |
| [first\_name](#input\_first\_name) | First name of the user (works only with `type = PERSON`) | `string` | `null` | no |
| [generate\_password](#input\_generate\_password) | Generate a random password using Terraform | `bool` | `false` | no |
| [generate\_rsa\_key](#input\_generate\_rsa\_key) | Whether automatically generate an RSA key - IMPORTANT
The private key generated by this resource will be stored
unencrypted in your Terraform state file.
Use of this resource for production deployments is not recommended. | `bool` | `false` | no |
| [grant\_default\_roles](#input\_grant\_default\_roles) | Whether to grant default\_role to Snowflake User | `bool` | `true` | no |
| [ignore\_changes\_on\_defaults](#input\_ignore\_changes\_on\_defaults) | Whether to ignore configuration of `default_warehouse`, `default_role` and `default_namespace` (works only with `type = PERSON`) | `bool` | `false` | no |
| [last\_name](#input\_last\_name) | Last name of the user (works only with `type = PERSON`) | `string` | `null` | no |
| [log\_level](#input\_log\_level) | Specifies the severity level of messages that should be ingested and made available in the active event table. Messages at the specified level (and at more severe levels) are ingested. | `string` | `null` | no |
| [login\_name](#input\_login\_name) | The name users use to log in. If not supplied, snowflake will use name instead. | `string` | `null` | no |
| [middle\_name](#input\_middle\_name) | Middle name of the user (works only with `type = PERSON`) | `string` | `null` | no |
| [must\_change\_password](#input\_must\_change\_password) | Should the user change the password on login. Should be set to true for non service account users | `bool` | `true` | no |
| [name](#input\_name) | Name of the resource | `string` | n/a | yes |
| [name\_scheme](#input\_name\_scheme) | Naming scheme configuration for the resource. This configuration is used to generate names using context provider:
- `properties` - list of properties to use when creating the name - is superseded by `var.context_templates`
- `delimiter` - delimited used to create the name from `properties` - is superseded by `var.context_templates`
- `context_template_name` - name of the context template used to create the name
- `replace_chars_regex` - regex to use for replacing characters in property-values created by the provider - any characters that match the regex will be removed from the name
- `extra_values` - map of extra label-value pairs, used to create a name
- `uppercase` - convert name to uppercase |
object({
properties = optional(list(string), ["environment", "name"])
delimiter = optional(string, "_")
context_template_name = optional(string, "snowflake-user")
replace_chars_regex = optional(string, "[^a-zA-Z0-9_]")
extra_values = optional(map(string))
uppercase = optional(bool, true)
}) | `{}` | no |
| [network\_policy](#input\_network\_policy) | Specifies the network policy to enforce for your account. Network policies enable restricting access to your account based on users’ IP address. | `string` | `null` | no |
| [query\_tag](#input\_query\_tag) | Optional string that can be used to tag queries and other SQL statements executed within a session. | `string` | `null` | no |
| [rsa\_public\_key](#input\_rsa\_public\_key) | Specifies the user's RSA public key; used for key-pair authentication. Must be on 1 line without header and trailer. | `string` | `null` | no |
| [rsa\_public\_key\_2](#input\_rsa\_public\_key\_2) | Specifies the user's second RSA public key; used to rotate the public and private keys
for key-pair authentication based on an expiration schedule set by your organization.
Must be on 1 line without header and trailer." | `string` | `null` | no |
| [timezone](#input\_timezone) | Specifies the time zone for the session. You can specify a time zone name or a link name from release 2021a of the IANA Time Zone Database (e.g. America/Los\_Angeles, Europe/London, UTC, Etc/GMT, etc.). | `string` | `null` | no |
| [trace\_level](#input\_trace\_level) | Controls how trace events are ingested into the event table. | `string` | `null` | no |
| [type](#input\_type) | Type of the user. Valid values are PERSON, SERVICE, LEGACY\_SERVICE | `string` | `"PERSON"` | no |
## Modules
No modules.
## Outputs
| Name | Description |
|------|-------------|
| [default\_namespace](#output\_default\_namespace) | Specifies the namespace (database only or database and schema) that is active by default for the user's session upon login |
| [default\_role](#output\_default\_role) | Specifies the role that is active by default for the user's session upon login |
| [default\_secondary\_roles\_option](#output\_default\_secondary\_roles\_option) | Specifies the secondary roles that are active for the user’s session upon login |
| [default\_warehouse](#output\_default\_warehouse) | Specifies the virtual warehouse that is active by default for the user's session upon login |
| [disable\_mfa](#output\_disable\_mfa) | Whether multi-factor authentication is disabled for the user |
| [disabled](#output\_disabled) | Whether user account is disabled |
| [display\_name](#output\_display\_name) | Name displayed for the user in the Snowflake web interface |
| [email](#output\_email) | Email address for the user |
| [enable\_unredacted\_query\_syntax\_error](#output\_enable\_unredacted\_query\_syntax\_error) | Enable access to unredacted query syntax error for the user |
| [first\_name](#output\_first\_name) | First name of the user (only if `type == PERSON`) |
| [last\_name](#output\_last\_name) | Last name of the user (only if `type == PERSON`) |
| [log\_level](#output\_log\_level) | Log level |
| [login\_name](#output\_login\_name) | The name users use to log in |
| [middle\_name](#output\_middle\_name) | Middle name of the user (only if `type == PERSON`) |
| [name](#output\_name) | Name of the user |
| [network\_policy](#output\_network\_policy) | Network policy associated with the user |
| [password](#output\_password) | Password set for the user (only if `type == PERSON` or `type == LEGACY_SERVICE`) |
| [query\_tag](#output\_query\_tag) | Query tag |
| [rsa\_private\_key](#output\_rsa\_private\_key) | RSA Private key used for authentication |
| [timezone](#output\_timezone) | Timezone |
| [trace\_level](#output\_trace\_level) | Trace level |
| [type](#output\_type) | User type |
## Providers
| Name | Version |
|------|---------|
| [context](#provider\_context) | >=0.4.0 |
| [random](#provider\_random) | >= 3.0.0 |
| [snowflake](#provider\_snowflake) | >= 0.96 |
| [tls](#provider\_tls) | ~> 4.0 |
## Requirements
| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.3.0 |
| [context](#requirement\_context) | >=0.4.0 |
| [random](#requirement\_random) | >= 3.0.0 |
| [snowflake](#requirement\_snowflake) | >= 0.96 |
| [tls](#requirement\_tls) | ~> 4.0 |
## Resources
| Name | Type |
|------|------|
| [random_password.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
| [snowflake_grant_account_role.default_role](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/grant_account_role) | resource |
| [snowflake_legacy_service_user.this](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/legacy_service_user) | resource |
| [snowflake_service_user.this](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/service_user) | resource |
| [snowflake_user.defaults_not_enforced](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/user) | resource |
| [snowflake_user.this](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs/resources/user) | resource |
| [tls_private_key.this](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key) | resource |
| [context_label.this](https://registry.terraform.io/providers/cloudposse/context/latest/docs/data-sources/label) | data source |
## CONTRIBUTING
Contributions are very welcomed!
Start by reviewing [contribution guide](CONTRIBUTING.md) and our [code of conduct](CODE_OF_CONDUCT.md). After that, start coding and ship your changes by creating a new PR.
## LICENSE
Apache 2 Licensed. See [LICENSE](LICENSE) for full details.
## AUTHORS
Made with [contrib.rocks](https://contrib.rocks).