Randomize user passwords on creation.
joshua-rutherford opened this issue · comments
Despite the comment here it seems that the password
field of the user resource is not fully ignored on updates.
Based the behavior of the API (i.e., the user password can only be written, never read) it is generally a bad idea to store the password in the the resource state because it will result in terraform detecting that changes need to be made to the remote despite there not being any ability to actually confirm that it has or has not changed on subsequent reads. As a result, I have to create the user and immediately remove the password to prevent terraform plan
and terraform apply
from thinking there is a change as shown below.
~ resource "gsuite_user" "REDACTED" {
2s_enforced = false
2s_enrolled = false
aliases = [
"REDACTED",
]
change_password_next_login = true
creation_time = "2020-01-07T18:44:43.000Z"
customer_id = "REDACTED"
etag = "\"REDACTED\""
id = "REDACTED"
include_in_global_list = true
is_admin = false
is_delegated_admin = false
is_ip_whitelisted = false
is_mailbox_setup = true
is_suspended = false
last_login_time = "1970-01-01T00:00:00.000Z"
name = {
"family_name" = "REDACTED"
"given_name" = "REDACTED"
}
org_unit_path = "/"
+ password = "cRVI0KB75**kyq"
primary_email = "REDACTED"
recovery_email = "REDACTED"
}
Additionally, the change_password_next_login
field should be omitted from terraform state as it will become out of sync when the user manually changes their password (as they should) on their next login.
Both of the above prevent me from using this resource in an automated way in a CI/CD pipeline. I propose a slight modification to the behavior.
- Omit both
password
andchange_password_next_login
from the resource to prevent terraform from tracking them at all. - Set a password on creation only using one of two methods:
a. At the provider level such that all newly created users get the same password.
b. At the resource level such that the initial password is randomly generated. - Set the
change_password_next_login
true on creation only.
The only down side to this is that with random password generation we must get it out of terraform some way and I'm not sure the best way.
Upon actually beginning to implement this I want to do two things:
- Allow a user to provide the initial password and
- Allow the user to keep the initial password out of their repositories.
So my thinking right now is to keep the password
and hash_function
properties and drop the change_password_next_login
. We'd only populate the password
, hash_function
and change_password_next_login
fields on creation only and leave them empty on all updates and imports. The change_password_next_login
field would be initialized to true
.
As a result, you can do the following:
resource "random_password" "keyser_soze" {
length = 16
special = true
}
resource "gsuite_user" "keyser_soze" {
...
password = random_password.keyser_soze.result
hash_function = "crypt"
}
And the state would contain the unhashed password which can be retrieved like:
terraform state show 'random_password.keyser_soze'