From 5110563099f42f8b80429356390e6afbe79f33cf Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 9 Jul 2019 01:47:15 -0400 Subject: [PATCH 1/3] resource/aws_iam_policy_attachment: Bypass `NoSuchEntity` error when detaching groups, roles, and users (support group, role, and user renames) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/5417 Previously from acceptance testing (before code updates): ``` --- FAIL: TestAccAWSIAMPolicyAttachment_Groups_RenamedGroup (8.82s) testing.go:568: Step 1 error: errors during apply: Error: [WARN] Error updating user, role, or group list from IAM Policy Attachment tf-acc-test-5552018730471644331: – NoSuchEntity: The group with name tf-acc-test-5552018730471644331-1 cannot be found. --- FAIL: TestAccAWSIAMPolicyAttachment_Roles_RenamedRole (10.31s) testing.go:568: Step 1 error: errors during apply: Error: [WARN] Error updating user, role, or group list from IAM Policy Attachment tf-acc-test-4256997168279122998: – NoSuchEntity: The role with name tf-acc-test-4256997168279122998-1 cannot be found. --- FAIL: TestAccAWSIAMPolicyAttachment_Users_RenamedUser (11.64s) testing.go:568: Step 1 error: errors during apply: Error: [WARN] Error updating user, role, or group list from IAM Policy Attachment tf-acc-test-5706224507827321055: – NoSuchEntity: The user with name tf-acc-test-5706224507827321055-1 cannot be found. ``` Output from acceptance testing: ``` --- PASS: TestAccAWSIAMPolicyAttachment_Groups_RenamedGroup (12.29s) --- PASS: TestAccAWSIAMPolicyAttachment_Users_RenamedUser (12.51s) --- PASS: TestAccAWSIAMPolicyAttachment_Roles_RenamedRole (12.92s) --- PASS: TestAccAWSIAMPolicyAttachment_basic (137.55s) --- PASS: TestAccAWSIAMPolicyAttachment_paginatedEntities (216.36s) ``` --- aws/resource_aws_iam_policy_attachment.go | 9 + ...resource_aws_iam_policy_attachment_test.go | 204 ++++++++++++++++++ 2 files changed, 213 insertions(+) diff --git a/aws/resource_aws_iam_policy_attachment.go b/aws/resource_aws_iam_policy_attachment.go index 5cf0b47b81b..d8009017be5 100644 --- a/aws/resource_aws_iam_policy_attachment.go +++ b/aws/resource_aws_iam_policy_attachment.go @@ -336,6 +336,9 @@ func detachPolicyFromUsers(conn *iam.IAM, users []*string, arn string) error { UserName: u, PolicyArn: aws.String(arn), }) + if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { + continue + } if err != nil { return err } @@ -348,6 +351,9 @@ func detachPolicyFromRoles(conn *iam.IAM, roles []*string, arn string) error { RoleName: r, PolicyArn: aws.String(arn), }) + if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { + continue + } if err != nil { return err } @@ -360,6 +366,9 @@ func detachPolicyFromGroups(conn *iam.IAM, groups []*string, arn string) error { GroupName: g, PolicyArn: aws.String(arn), }) + if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { + continue + } if err != nil { return err } diff --git a/aws/resource_aws_iam_policy_attachment_test.go b/aws/resource_aws_iam_policy_attachment_test.go index 5fc6a79ac5c..bd8208ba448 100644 --- a/aws/resource_aws_iam_policy_attachment_test.go +++ b/aws/resource_aws_iam_policy_attachment_test.go @@ -77,6 +77,99 @@ func TestAccAWSIAMPolicyAttachment_paginatedEntities(t *testing.T) { }) } +func TestAccAWSIAMPolicyAttachment_Groups_RenamedGroup(t *testing.T) { + var out iam.ListEntitiesForPolicyOutput + + rName := acctest.RandomWithPrefix("tf-acc-test") + groupName1 := fmt.Sprintf("%s-1", rName) + groupName2 := fmt.Sprintf("%s-2", rName) + resourceName := "aws_iam_policy_attachment.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSPolicyAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSIamPolicyAttachmentConfigGroupsRenamedGroup(rName, groupName1), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSPolicyAttachmentExists(resourceName, 1, &out), + testAccCheckAWSPolicyAttachmentAttributes([]string{}, []string{}, []string{groupName1}, &out), + ), + }, + { + Config: testAccAWSIamPolicyAttachmentConfigGroupsRenamedGroup(rName, groupName2), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSPolicyAttachmentExists(resourceName, 1, &out), + testAccCheckAWSPolicyAttachmentAttributes([]string{}, []string{}, []string{groupName2}, &out), + ), + }, + }, + }) +} + +func TestAccAWSIAMPolicyAttachment_Roles_RenamedRole(t *testing.T) { + var out iam.ListEntitiesForPolicyOutput + + rName := acctest.RandomWithPrefix("tf-acc-test") + roleName1 := fmt.Sprintf("%s-1", rName) + roleName2 := fmt.Sprintf("%s-2", rName) + resourceName := "aws_iam_policy_attachment.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSPolicyAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSIamPolicyAttachmentConfigRolesRenamedRole(rName, roleName1), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSPolicyAttachmentExists(resourceName, 1, &out), + testAccCheckAWSPolicyAttachmentAttributes([]string{}, []string{roleName1}, []string{}, &out), + ), + }, + { + Config: testAccAWSIamPolicyAttachmentConfigRolesRenamedRole(rName, roleName2), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSPolicyAttachmentExists(resourceName, 1, &out), + testAccCheckAWSPolicyAttachmentAttributes([]string{}, []string{roleName2}, []string{}, &out), + ), + }, + }, + }) +} + +func TestAccAWSIAMPolicyAttachment_Users_RenamedUser(t *testing.T) { + var out iam.ListEntitiesForPolicyOutput + + rName := acctest.RandomWithPrefix("tf-acc-test") + userName1 := fmt.Sprintf("%s-1", rName) + userName2 := fmt.Sprintf("%s-2", rName) + resourceName := "aws_iam_policy_attachment.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSPolicyAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSIamPolicyAttachmentConfigUsersRenamedUser(rName, userName1), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSPolicyAttachmentExists(resourceName, 1, &out), + testAccCheckAWSPolicyAttachmentAttributes([]string{userName1}, []string{}, []string{}, &out), + ), + }, + { + Config: testAccAWSIamPolicyAttachmentConfigUsersRenamedUser(rName, userName2), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSPolicyAttachmentExists(resourceName, 1, &out), + testAccCheckAWSPolicyAttachmentAttributes([]string{userName2}, []string{}, []string{}, &out), + ), + }, + }, + }) +} + func testAccCheckAWSPolicyAttachmentDestroy(s *terraform.State) error { return nil } @@ -483,3 +576,114 @@ resource "aws_iam_policy_attachment" "test-paginated-attach" { } `, userNamePrefix, policyName, attachmentName) } + +func testAccAWSIamPolicyAttachmentConfigGroupsRenamedGroup(rName, groupName string) string { + return fmt.Sprintf(` +resource "aws_iam_policy" "test" { + name = %[1]q + + policy = < Date: Tue, 9 Jul 2019 01:48:19 -0400 Subject: [PATCH 2/3] docs/resource/aws_iam_role: Note force_detach_policies argument requirement for modifying name/path with aws_iam_policy_attachment Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/5417 --- website/docs/r/iam_role.html.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docs/r/iam_role.html.markdown b/website/docs/r/iam_role.html.markdown index 69e8de38937..6b27a7bad8c 100644 --- a/website/docs/r/iam_role.html.markdown +++ b/website/docs/r/iam_role.html.markdown @@ -10,6 +10,8 @@ description: |- Provides an IAM role. +~> *NOTE:* If policies are attached to the role via the [`aws_iam_policy_attachment` resource](/docs/providers/aws/r/iam_policy_attachment.html) and you are modifying the role `name` or `path`, the `force_detach_policies` argument must be set to `true` and applied before attempting the operation otherwise you will encounter a `DeleteConflict` error. The [`aws_iam_role_policy_attachment` resource (recommended)](/docs/providers/aws/r/iam_role_policy_attachment.html) does not have this requirement. + ## Example Usage ```hcl From a3390188fe6f20b11284dc55a556c97d1bc77ed1 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 9 Jul 2019 01:48:34 -0400 Subject: [PATCH 3/3] docs/resource/aws_iam_user: Note force_destroy argument requirement for modifying name/path with aws_iam_policy_attachment Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/5417 --- website/docs/r/iam_user.html.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docs/r/iam_user.html.markdown b/website/docs/r/iam_user.html.markdown index a78d4e4f973..626e3e0c5f6 100644 --- a/website/docs/r/iam_user.html.markdown +++ b/website/docs/r/iam_user.html.markdown @@ -10,6 +10,8 @@ description: |- Provides an IAM user. +~> *NOTE:* If policies are attached to the user via the [`aws_iam_policy_attachment` resource](/docs/providers/aws/r/iam_policy_attachment.html) and you are modifying the user `name` or `path`, the `force_destroy` argument must be set to `true` and applied before attempting the operation otherwise you will encounter a `DeleteConflict` error. The [`aws_iam_user_policy_attachment` resource (recommended)](/docs/providers/aws/r/iam_user_policy_attachment.html) does not have this requirement. + ## Example Usage ```hcl