hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.74k stars 9.1k forks source link

[Bug]: cognito-idp module ignores message_action on user update #28210

Open peov opened 1 year ago

peov commented 1 year ago

Terraform Core Version

1.3.6

AWS Provider Version

4.45.0

Affected Resource(s)

aws_cognito_user

Expected Behavior

Use case: A cognito user pool with a mixture of human and technical users is maintained as IaC in a Git Repository using Terraform. After initial setup to this solution, a few users where on holiday and others forgot, so some of the created users had their initial password expire and are stuck in FORCE_CHANGE_PASSWORD now. We want to send them new temporary passwords and reset the expiration on their cognito users.

Attempted solution: When specifying the optional "message_action" parameter with value "RESEND" to an existing user, we expected new mails being sent out on executing terraform apply. The user is specified as follows:

resource "aws_cognito_user" "username" {
  user_pool_id = "pool_id"
  username = "username"
  desired_delivery_mediums = ["EMAIL"]
  message_action = "RESEND"
  attributes = {
    email = "mail@me.com"
    email_verified = true
  }
}

Where "message_action" = "RESEND" is the only change in the state.

Actual Behavior

Terraform attempts an in-place update. However, during Update as seen in "github.com/hashicorp/terraform-provider-aws/internal/service/cognitoidp/user", function resourceUserUpdate() completely ignores the message_action field. This prevents the functionality of the field if the user already exists, defeating the purpose of the RESEND option.

Possible solutions are:

  1. Make message_action a breaking change to the resource, meaning that create is called instead of update
  2. Add something like the following
    if d.HasChange("message_action") {
    ResourceUserCreate(d, meta)
    }

As replacing users might have impact on another end and might not be possible for the runtime based on the permission set (deleting users is prohibited in our pipeline environment for example, as destructive actions need to be called from a seperate process), I suggest 2) even though it requires a bit of overhead. As the AWS API specifies, message_action is a parameter of AdminCreateUser, meaning all parameters need to be supplied again as if the user was just created, which is why the snippet of 2) refers to the creating functionality. A solution "2b)" would be to implement it out in ResourceUserUpdate to get better logging etc., but that would create even more overhead

Relevant Error/Panic Output Snippet

No response

Terraform Configuration Files

versions.tf

terraform {
  required_providers {
    aws = {
      version = "=4.45.0"
      source = "hashicorp/aws"
    }
  }
  required_version = ">1.3.6"

provider.tf

provider "aws {
  region = "eu-central-1"
  assume_role {
    role_arn = <arn>
    session_name = "Terraform"
  }
}

backend.tf

terraform {
  backend "http" {
    address = <gitlab backend>
    lock_address = ...
    unlock_address = ...
    lock_method = "POST"
    unlock_method = "DELETE"
    username = gitlab-ci-token
  }
}

Steps to Reproduce

  1. Create a Cognito User using Terraform
  2. Have the users temporary password expire
  3. Specify message_action = "RESEND" for that user
  4. Apply again
  5. New Message is not sent

Debug Output

No response

Panic Output

No response

Important Factoids

Troubleshooting conducted via CloudTrail logs. The corresponding aws-cli command necessary to produce the actual expected behavior, which sent the message and created an AdminCreateUser entry in CloudTrail:

aws cognito-idp admin-create-user --user-pool-id pool_id --username username --desired-delivery-mediums EMAIL --message-action RESEND --user-attributes Name=email,Value=mail@me.com Name=email_verifies,Value=true

The Terraform Apply just created an AdminGetUser call, without making any changes.

References

AWS cognito-idp admin-create-user API reference

Would you like to implement a fix?

Yes

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

peov commented 1 year ago

Because the AWS API is fairly restrictive in message_action usage I decided to do a full-implementation in the Update function in my PR. To avoid duplicate code I have extracted some functionality into it's own function.

peov commented 1 year ago

Hi @justinretzolk , is there anything I can do to push this forward? I have since published my own fork of the provider, but it is really cumbersome to override a default/official one and I have had my fair set of issues with it.

justinretzolk commented 1 year ago

Hey @peov 👋 Thank you for checking in on this, and apologies for the delayed reply! Unfortunately I can't provide an ETA on when this will be reviewed/merged due to the potential of shifting priorities. We prioritize by count of :+1: reactions and a few other things (more information on our prioritization guide if you're interested).

excalq commented 6 months ago

Given the lack of availability to reissue an invite from the AWS Web Console, this functionality would be very welcome. The current state feels broken and takes time to investigate why it's not working as documented. A side-effect of the current functionality is forcing Terraform users to set longer temporary-password expiration times, which is a security regression.