DeviaVir / terraform-provider-gsuite

A @HashiCorp Terraform provider for managing G Suite resources.
MIT License
271 stars 77 forks source link

Randomize user passwords on creation. #119

Open joshua-rutherford opened 4 years ago

joshua-rutherford commented 4 years ago

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.

  1. Omit both password and change_password_next_login from the resource to prevent terraform from tracking them at all.
  2. 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.
  3. 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.

joshua-rutherford commented 4 years ago

Upon actually beginning to implement this I want to do two things:

  1. Allow a user to provide the initial password and
  2. 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'