From d34aca99e190a4c4160f393737b2f56406ebb35f Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 22 Mar 2021 22:37:06 -0400 Subject: [PATCH] retry on ResourceConflictException during creation --- .changelog/18341.txt | 3 + ..._securityhub_organization_admin_account.go | 18 ++++- ...rityhub_organization_admin_account_test.go | 69 +++++++++++++++++++ aws/resource_aws_securityhub_test.go | 5 +- 4 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 .changelog/18341.txt diff --git a/.changelog/18341.txt b/.changelog/18341.txt new file mode 100644 index 00000000000..e732da43402 --- /dev/null +++ b/.changelog/18341.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_securityhub_organization_admin_account: Retry on `ResourceConflictException` error during creation +``` \ No newline at end of file diff --git a/aws/resource_aws_securityhub_organization_admin_account.go b/aws/resource_aws_securityhub_organization_admin_account.go index 0f1846c37f5..cec3e044478 100644 --- a/aws/resource_aws_securityhub_organization_admin_account.go +++ b/aws/resource_aws_securityhub_organization_admin_account.go @@ -7,9 +7,11 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/securityhub" "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/securityhub/finder" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/securityhub/waiter" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) func resourceAwsSecurityHubOrganizationAdminAccount() *schema.Resource { @@ -42,7 +44,21 @@ func resourceAwsSecurityHubOrganizationAdminAccountCreate(d *schema.ResourceData AdminAccountId: aws.String(adminAccountID), } - _, err := conn.EnableOrganizationAdminAccount(input) + err := resource.Retry(waiter.AdminAccountEnabledTimeout, func() *resource.RetryError { + _, err := conn.EnableOrganizationAdminAccount(input) + + if err != nil { + if tfawserr.ErrCodeEquals(err, securityhub.ErrCodeResourceConflictException) { + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + + if tfresource.TimedOut(err) { + _, err = conn.EnableOrganizationAdminAccount(input) + } if err != nil { return fmt.Errorf("error enabling Security Hub Organization Admin Account (%s): %w", adminAccountID, err) diff --git a/aws/resource_aws_securityhub_organization_admin_account_test.go b/aws/resource_aws_securityhub_organization_admin_account_test.go index 84ae639ea33..e720cbf56fe 100644 --- a/aws/resource_aws_securityhub_organization_admin_account_test.go +++ b/aws/resource_aws_securityhub_organization_admin_account_test.go @@ -7,6 +7,7 @@ import ( "github.com/aws/aws-sdk-go/service/securityhub" "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/securityhub/finder" ) @@ -63,6 +64,35 @@ func testAccAwsSecurityHubOrganizationAdminAccount_disappears(t *testing.T) { }) } +func testAccAwsSecurityHubOrganizationAdminAccount_MultiRegion(t *testing.T) { + var providers []*schema.Provider + + resourceName := "aws_securityhub_organization_admin_account.test" + altResourceName := "aws_securityhub_organization_admin_account.alternate" + thirdResourceName := "aws_securityhub_organization_admin_account.third" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccOrganizationsAccountPreCheck(t) + testAccMultipleRegionPreCheck(t, 3) + }, + ErrorCheck: testAccErrorCheck(t, securityhub.EndpointsID), + ProviderFactories: testAccProviderFactoriesMultipleRegion(&providers, 3), + CheckDestroy: testAccCheckAwsSecurityHubOrganizationAdminAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSecurityHubOrganizationAdminAccountConfigMultiRegion(), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsSecurityHubOrganizationAdminAccountExists(resourceName), + testAccCheckAwsSecurityHubOrganizationAdminAccountExists(altResourceName), + testAccCheckAwsSecurityHubOrganizationAdminAccountExists(thirdResourceName), + ), + }, + }, + }) +} + func testAccCheckAwsSecurityHubOrganizationAdminAccountDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).securityhubconn @@ -136,3 +166,42 @@ resource "aws_securityhub_organization_admin_account" "test" { } ` } + +func testAccSecurityHubOrganizationAdminAccountConfigMultiRegion() string { + return composeConfig( + testAccMultipleRegionProviderConfig(3), + ` +data "aws_caller_identity" "current" {} + +data "aws_partition" "current" {} + +resource "aws_organizations_organization" "test" { + aws_service_access_principals = ["securityhub.${data.aws_partition.current.dns_suffix}"] + feature_set = "ALL" +} + +resource "aws_securityhub_account" "test" {} + +resource "aws_securityhub_organization_admin_account" "test" { + depends_on = [aws_organizations_organization.test] + + admin_account_id = data.aws_caller_identity.current.account_id +} + +resource "aws_securityhub_organization_admin_account" "alternate" { + provider = awsalternate + + depends_on = [aws_organizations_organization.test] + + admin_account_id = data.aws_caller_identity.current.account_id +} + +resource "aws_securityhub_organization_admin_account" "third" { + provider = awsthird + + depends_on = [aws_organizations_organization.test] + + admin_account_id = data.aws_caller_identity.current.account_id +} +`) +} diff --git a/aws/resource_aws_securityhub_test.go b/aws/resource_aws_securityhub_test.go index e65452d1160..30ae8950a97 100644 --- a/aws/resource_aws_securityhub_test.go +++ b/aws/resource_aws_securityhub_test.go @@ -23,8 +23,9 @@ func TestAccAWSSecurityHub_serial(t *testing.T) { "basic": testAccAWSSecurityHubInviteAccepter_basic, }, "OrganizationAdminAccount": { - "basic": testAccAwsSecurityHubOrganizationAdminAccount_basic, - "disappears": testAccAwsSecurityHubOrganizationAdminAccount_disappears, + "basic": testAccAwsSecurityHubOrganizationAdminAccount_basic, + "disappears": testAccAwsSecurityHubOrganizationAdminAccount_disappears, + "MultiRegion": testAccAwsSecurityHubOrganizationAdminAccount_MultiRegion, }, "ProductSubscription": { "basic": testAccAWSSecurityHubProductSubscription_basic,