Skip to content

Commit

Permalink
Attempt to clean up CF IAM users
Browse files Browse the repository at this point in the history
Periodic tests seemed to get into a failure loop because an IAM user
with the same name already existed, which is not allowed. This then
failed the entire CloudFoundation stack. Depite the stack claiming to
have been rolled back, the next iteration would run into the same
problem.

This change includes IAM users in the list of resources we need to
specifically delete in the case of a CloudFoundation failure, just in
case they've leaked

Signed-off-by: Nolan Brubaker <[email protected]>
  • Loading branch information
nrb committed Dec 6, 2024
1 parent 9b65314 commit a3bedc8
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions test/e2e/shared/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ func deleteResourcesInCloudFormation(prov client.ConfigProvider, t *cfn_bootstra
iamSvc := iam.New(prov)
temp := *renderCustomCloudFormation(t)
var (
iamUsers []*cfn_iam.User
iamRoles []*cfn_iam.Role
instanceProfiles []*cfn_iam.InstanceProfile
policies []*cfn_iam.ManagedPolicy
Expand All @@ -484,6 +485,9 @@ func deleteResourcesInCloudFormation(prov client.ConfigProvider, t *cfn_bootstra
// temp.Resources is a map. Traversing that directly results in undetermined order.
for _, val := range temp.Resources {
switch val.AWSCloudFormationType() {
case configservice.ResourceTypeAwsIamUser:
user := val.(*cfn_iam.User)
iamUsers = append(iamUsers, user)
case configservice.ResourceTypeAwsIamRole:
role := val.(*cfn_iam.Role)
iamRoles = append(iamRoles, role)
Expand All @@ -498,6 +502,19 @@ func deleteResourcesInCloudFormation(prov client.ConfigProvider, t *cfn_bootstra
groups = append(groups, group)
}
}
for _, user := range iamUsers {
By(fmt.Sprintf("deleting the following user: %q", user.UserName))
repeat := false
Eventually(func(gomega Gomega) bool {
err := DeleteUser(prov, user.UserName)
if err != nil && !repeat {
By(fmt.Sprintf("failed to delete user '%q'; reason: %+v", user.UserName, err))
repeat = true
}
code, ok := awserrors.Code(err)
return err == nil || (ok && code == iam.ErrCodeNoSuchEntityException)
}, 5*time.Minute, 5*time.Second).Should(BeTrue(), fmt.Sprintf("Eventually failed deleting the user: %q", user.UserName))
}
for _, role := range iamRoles {
By(fmt.Sprintf("deleting the following role: %s", role.RoleName))
repeat := false
Expand Down Expand Up @@ -598,6 +615,28 @@ func detachAllPoliciesForRole(prov client.ConfigProvider, name string) error {
return nil
}

// DeleteUser deletes an IAM user in a best effort manner.
func DeleteUser(prov client.ConfigProvider, name string) error {
iamSvc := iam.New(prov)

// if role does not exist, return.
_, err := iamSvc.GetUser(&iam.GetUserInput{UserName: aws.String(name)})
if err != nil {
return err
}

//if err := detachAllPoliciesForRole(prov, name); err != nil {

Check failure on line 628 in test/e2e/shared/aws.go

View workflow job for this annotation

GitHub Actions / lint

commentFormatting: put a space between `//` and comment text (gocritic)

Check failure on line 628 in test/e2e/shared/aws.go

View workflow job for this annotation

GitHub Actions / lint

commentFormatting: put a space between `//` and comment text (gocritic)
// return err
//}

_, err = iamSvc.DeleteUser(&iam.DeleteUserInput{UserName: aws.String(name)})
if err != nil {
return err
}

return nil
}

// DeleteRole deletes roles in a best effort manner.
func DeleteRole(prov client.ConfigProvider, name string) error {
iamSvc := iam.New(prov)
Expand Down

0 comments on commit a3bedc8

Please sign in to comment.