-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New resource for AppStream User and Stack User Association #21485
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, @coderGo93. I have a number of suggested changes.
internal/service/appstream/user.go
Outdated
_, err = conn.CreateUserWithContext(ctx, input) | ||
} | ||
if err != nil { | ||
return diag.FromErr(fmt.Errorf("error creating Appstream User (%s): %w", d.Id(), err)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error and log messages should use the name that AWS uses, "AppStream"
return diag.FromErr(fmt.Errorf("error creating Appstream User (%s): %w", d.Id(), err)) | |
return diag.FromErr(fmt.Errorf("error creating AppStream User (%s): %w", d.Id(), err)) |
err = resource.RetryContext(ctx, fleetOperationTimeout, func() *resource.RetryError { | ||
output, err = conn.BatchAssociateUserStackWithContext(ctx, &appstream.BatchAssociateUserStackInput{ | ||
UserStackAssociations: []*appstream.UserStackAssociation{input}, | ||
}) | ||
if err != nil { | ||
if tfawserr.ErrCodeEquals(err, appstream.ErrCodeResourceNotFoundException) { | ||
return resource.RetryableError(err) | ||
} | ||
|
||
return resource.NonRetryableError(err) | ||
} | ||
|
||
return nil | ||
}) | ||
|
||
if tfresource.TimedOut(err) { | ||
output, err = conn.BatchAssociateUserStackWithContext(ctx, &appstream.BatchAssociateUserStackInput{ | ||
UserStackAssociations: []*appstream.UserStackAssociation{input}, | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need a Retry
loop? The documentation for BatchAssociateUserStack
seems to indicate that the function is synchronous.
{ | ||
Config: testAccStackUserAssociationConfig(rName, authType, rEmail), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckStackUserAssociationExists(resourceName), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should check all parameter values
resourceName := "aws_appstream_stack_user_association.test" | ||
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) | ||
authType := "USERPOOL" | ||
rEmail := acctest.RandomEmailAddress("hashicorp.com") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use a random domain name generated by acctest.RandomDomainName()
, to avoid being delivered to an actual email address.
rEmail := acctest.RandomEmailAddress("hashicorp.com") | |
domain := acctest.RandomDomainName() | |
rEmail := acctest.RandomEmailAddress(domain) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates, @coderGo93. There are a few things to change from the initial review plus some I've added to this review.
I've also added a commit to show what I meant about returning resource.NotFoundError
from the FindUserByUserNameAndAuthType()
function in #21485 (comment)
internal/service/appstream/user.go
Outdated
// Enabling/disabling workflow | ||
if v, ok := d.GetOk("enabled"); ok { | ||
if v.(bool) { | ||
input := &appstream.EnableUserInput{ | ||
AuthenticationType: aws.String(authType), | ||
UserName: aws.String(userName), | ||
} | ||
|
||
_, err = conn.EnableUserWithContext(ctx, input) | ||
if err != nil { | ||
return diag.FromErr(fmt.Errorf("error enabling AppStream User (%s): %w", d.Id(), err)) | ||
} | ||
} else { | ||
input := &appstream.DisableUserInput{ | ||
AuthenticationType: aws.String(authType), | ||
UserName: aws.String(userName), | ||
} | ||
|
||
_, err = conn.DisableUserWithContext(ctx, input) | ||
if err != nil { | ||
return diag.FromErr(fmt.Errorf("error disabling AppStream User (%s): %w", d.Id(), err)) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like users are enabled by default when they're created, so we only need to change this when enabled
is false
internal/service/appstream/wait.go
Outdated
// waitUserAvailable waits for a user be available | ||
func waitUserAvailable(ctx context.Context, conn *appstream.AppStream, username, authType string) (*appstream.User, error) { | ||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"NotFound"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the Refresh
function returns nil
for the resource value, the status isn't checked, so the Pending
list can be removed.
internal/service/appstream/wait.go
Outdated
func waitUserAvailable(ctx context.Context, conn *appstream.AppStream, username, authType string) (*appstream.User, error) { | ||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"NotFound"}, | ||
Target: []string{"AVAILABLE"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a constant shared with the status function
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { | ||
acctest.PreCheck(t) | ||
acctest.PreCheckHasIAMRole(t, "AmazonAppStreamServiceAccess") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creating AppStream User resources doesn't require this IAM role, so the check can be removed
|
||
for _, err := range output.Errors { | ||
errs = multierror.Append(errs, fmt.Errorf("%s: %s", aws.StringValue(err.ErrorCode), aws.StringValue(err.ErrorMessage))) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should return errs
, otherwise the errors collected here are ignored
} | ||
|
||
if len(resp.UserStackAssociations) == 0 { | ||
log.Printf("[WARN] Appstream User (%s) not found, removing from state", d.Id()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.Printf("[WARN] Appstream User (%s) not found, removing from state", d.Id()) | |
log.Printf("[WARN] AppStream User Stack Association (%s) not found, removing from state", d.Id()) |
}) | ||
|
||
if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, appstream.ErrCodeResourceNotFoundException) { | ||
log.Printf("[WARN] Appstream Stack User Association (%s) not found, removing from state", d.Id()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.Printf("[WARN] Appstream Stack User Association (%s) not found, removing from state", d.Id()) | |
log.Printf("[WARN] AppStream User Stack Association (%s) not found, removing from state", d.Id()) |
internal/service/appstream/user.go
Outdated
if v, ok := d.GetOk("message_action"); ok { | ||
input.MessageAction = aws.String(v.(string)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The message_action
parameter should be restored. In #21485 (comment), I was suggesting removing RESEND
as a valid option and ignoring changes to the value instead of making it ForceNew
. There should still be the options of sending the welcome email or setting SUPPRESS
to not send the email.
Another option would be to use a TypeBool
send_welcome_email
(or send_email_notification
to match aws_appstream_user_stack_association
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies, I misunderstood then, thanks for the clarification.
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter send_email_notification
should be restored here, so that the email notification can be controlled. In #21485 (comment), I meant that it should not be ForceNew
and that changes should be ignored, since it only has an effect at creation time
c65d4f5
to
40e7c23
Compare
…thentication Type are adjacent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @coderGo93. I've made a few updates to tweak the error messages and enhance the tests
Acceptance test results in Commercial partition
--- PASS: TestAccAppStreamUser_disappears (34.66s)
--- PASS: TestAccAppStreamUser_basic (45.50s)
--- PASS: TestAccAppStreamUserStackAssociation_disappears (49.88s)
--- PASS: TestAccAppStreamUserStackAssociation_basic (66.23s)
--- PASS: TestAccAppStreamUserStackAssociation_complete (78.13s)
--- PASS: TestAccAppStreamUser_complete (89.22s)
Acceptance test results in GovCloud (AppStream User pools are not supported in GovCloud)
--- SKIP: TestAccAppStreamUser_complete (15.94s)
--- SKIP: TestAccAppStreamUser_disappears (15.96s)
--- SKIP: TestAccAppStreamUser_basic (15.99s)
--- SKIP: TestAccAppStreamUserStackAssociation_basic (20.52s)
--- SKIP: TestAccAppStreamUserStackAssociation_complete (20.64s)
--- SKIP: TestAccAppStreamUserStackAssociation_disappears (20.79s)
This functionality has been released in v3.67.0 of the Terraform AWS Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you! |
I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. |
aws_appstream_user
aws_appstream_stack_user_association
Community Note
Relates #6508
Output from acceptance testing:
AppStream User and Stack User Association