diff --git a/README.md b/README.md index 3add7de..dcb62fa 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,9 @@ module "terraform_snowflake_user" { | [first\_name](#input\_first\_name) | First name of the user | `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 and default\_secondary\_roles to Snowflake User | `bool` | `true` | no | +| [grant\_default\_roles](#input\_grant\_default\_roles) | Whether to grant default\_role to Snowflake User | `bool` | `true` | no | | [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | +| [ignore\_changes\_on\_defaults](#input\_ignore\_changes\_on\_defaults) | Whether to ignore configuration of `default_warehouse`, `default_role` and `default_namespace` | `bool` | `false` | no | | [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no | | [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | | [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | @@ -122,6 +123,7 @@ module "terraform_snowflake_user" { |------|------| | [random_password.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | | [snowflake_role_grants.default_role](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/role_grants) | resource | +| [snowflake_user.defaults_not_enforced](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/user) | resource | | [snowflake_user.this](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/user) | resource | | [tls_private_key.this](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key) | resource | diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 4505e2d..75c1341 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -2,13 +2,26 @@ resource "snowflake_role" "user_role" { name = "SNOWFLAKE_USER_ROLE" } -module "terraform_snowflake_user" { +module "terraform_snowflake_user_1" { source = "../../" context = module.this.context - name = "snowflake-user" + name = "snowflake_user_1" generate_rsa_key = true generate_password = true default_role = resource.snowflake_role.user_role.name default_secondary_roles = ["ALL"] } + +module "terraform_snowflake_user_2" { + source = "../../" + context = module.this.context + name = "snowflake_user_2" + generate_rsa_key = true + generate_password = true + ignore_changes_on_defaults = false + grant_default_roles = true + + default_role = resource.snowflake_role.user_role.name + default_secondary_roles = ["ALL"] +} diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 5512e0b..ad35817 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -1,5 +1,11 @@ -output "user_module_outputs" { +output "user_module_outputs_1" { description = "All user module outputs" - value = module.terraform_snowflake_user + value = module.terraform_snowflake_user_1 + sensitive = true +} + +output "user_module_outputs_2" { + description = "All user module outputs" + value = module.terraform_snowflake_user_1 sensitive = true } diff --git a/locals.tf b/locals.tf index a7cb458..8ccf0bf 100644 --- a/locals.tf +++ b/locals.tf @@ -6,4 +6,6 @@ locals { rsa_public_key = var.generate_rsa_key ? join("", split("\n", trim(one(resource.tls_private_key.this[*].public_key_pem), "- \n BEGIN END PUBLIC KEY"))) : var.rsa_public_key generate_password = module.this.enabled && var.generate_password generate_rsa_key = module.this.enabled && var.generate_rsa_key + + snowflake_user = var.ignore_changes_on_defaults ? snowflake_user.defaults_not_enforced : snowflake_user.this } diff --git a/main.tf b/main.tf index e1647f5..f765b66 100644 --- a/main.tf +++ b/main.tf @@ -24,7 +24,7 @@ resource "random_password" "this" { } resource "snowflake_user" "this" { - count = module.this.enabled ? 1 : 0 + count = module.this.enabled && !var.ignore_changes_on_defaults ? 1 : 0 name = local.name_from_descriptor login_name = var.login_name @@ -47,9 +47,41 @@ resource "snowflake_user" "this" { rsa_public_key_2 = var.rsa_public_key_2 } +resource "snowflake_user" "defaults_not_enforced" { + count = module.this.enabled && var.ignore_changes_on_defaults ? 1 : 0 + + name = local.name_from_descriptor + login_name = var.login_name + display_name = var.display_name + comment = var.comment + + password = one(random_password.this[*].result) + must_change_password = var.must_change_password + + email = var.email + first_name = var.first_name + last_name = var.last_name + + default_namespace = var.default_namespace + default_warehouse = var.default_warehouse + default_role = var.default_role + default_secondary_roles = var.default_secondary_roles + + rsa_public_key = local.rsa_public_key + rsa_public_key_2 = var.rsa_public_key_2 + + lifecycle { + ignore_changes = [ + default_namespace, + default_warehouse, + default_role, + ] + } +} + resource "snowflake_role_grants" "default_role" { count = module.this.enabled && var.grant_default_roles && var.default_role != null ? 1 : 0 role_name = var.default_role - users = [one(resource.snowflake_user.this[*].name)] + users = [one(local.snowflake_user[*].name)] } diff --git a/outputs.tf b/outputs.tf index dea2ef3..2929af1 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,51 +1,51 @@ output "default_namespace" { description = "Specifies the namespace (database only or database and schema) that is active by default for the user's session upon login" - value = one(snowflake_user.this[*].default_namespace) + value = one(local.snowflake_user[*].default_namespace) } output "default_role" { description = "Specifies the role that is active by default for the user's session upon login" - value = one(snowflake_user.this[*].default_role) + value = one(local.snowflake_user[*].default_role) } output "default_warehouse" { description = "Specifies the virtual warehouse that is active by default for the user's session upon login" - value = one(snowflake_user.this[*].default_warehouse) + value = one(local.snowflake_user[*].default_warehouse) } output "disabled" { description = "Whether user account is disabled" - value = one(snowflake_user.this[*].disabled) + value = one(local.snowflake_user[*].disabled) } output "login_name" { description = "The name users use to log in" - value = one(snowflake_user.this[*].login_name) + value = one(local.snowflake_user[*].login_name) } output "name" { description = "Name of the user" - value = one(snowflake_user.this[*].name) + value = one(local.snowflake_user[*].name) } output "display_name" { description = "Name displayed for the user in the Snowflake web interface" - value = one(snowflake_user.this[*].display_name) + value = one(local.snowflake_user[*].display_name) } output "first_name" { description = "First name of the user" - value = one(snowflake_user.this[*].first_name) + value = one(local.snowflake_user[*].first_name) } output "last_name" { description = "Last name of the user" - value = one(snowflake_user.this[*].last_name) + value = one(local.snowflake_user[*].last_name) } output "email" { description = "Email address for the user" - value = one(snowflake_user.this[*].email) + value = one(local.snowflake_user[*].email) } output "password" { diff --git a/variables.tf b/variables.tf index 5ae9ac0..fbc6caa 100644 --- a/variables.tf +++ b/variables.tf @@ -112,7 +112,13 @@ variable "must_change_password" { } variable "grant_default_roles" { - description = "Whether to grant default_role and default_secondary_roles to Snowflake User" + description = "Whether to grant default_role to Snowflake User" type = bool default = true } + +variable "ignore_changes_on_defaults" { + description = "Whether to ignore configuration of `default_warehouse`, `default_role` and `default_namespace`" + type = bool + default = false +}