Skip to content
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

Destroy aws_ram_resource_share_accepter from member account when share contains some resource types #19718

Merged
3 changes: 3 additions & 0 deletions .changelog/19718.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_ram_resource_share_acceptor: Allow destroy even where AWS API provides no way to disassociate
```
7 changes: 6 additions & 1 deletion aws/resource_aws_ram_resource_share_accepter.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,16 @@ func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta inte

_, err := conn.DisassociateResourceShare(input)

if err != nil {
if tfawserr.ErrCodeEquals(err, ram.ErrCodeOperationNotPermittedException) {
log.Printf("[WARN] Resource share could not be disassociated, but continuing: %s", err)
}

if err != nil && !tfawserr.ErrCodeEquals(err, ram.ErrCodeOperationNotPermittedException) {
return fmt.Errorf("Error leaving RAM resource share: %s", err)
}

_, err = waiter.ResourceShareOwnedBySelfDisassociated(conn, d.Id(), d.Timeout(schema.TimeoutDelete))

if err != nil {
return fmt.Errorf("Error waiting for RAM resource share (%s) state: %s", d.Id(), err)
}
Expand Down
111 changes: 111 additions & 0 deletions aws/resource_aws_ram_resource_share_accepter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,45 @@ func TestAccAwsRamResourceShareAccepter_disappears(t *testing.T) {
})
}

func TestAccAwsRamResourceShareAccepter_resourceAssociation(t *testing.T) {
var providers []*schema.Provider
resourceName := "aws_ram_resource_share_accepter.test"
principalAssociationResourceName := "aws_ram_principal_association.test"
rName := acctest.RandomWithPrefix("tf-acc-test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccAlternateAccountPreCheck(t)
},
ErrorCheck: testAccErrorCheck(t, ram.EndpointsID),
ProviderFactories: testAccProviderFactoriesAlternate(&providers),
CheckDestroy: testAccCheckAwsRamResourceShareAccepterDestroy,
Steps: []resource.TestStep{
{
Config: testAccAwsRamResourceShareAccepterResourceAssociation(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsRamResourceShareAccepterExists(resourceName),
resource.TestCheckResourceAttrPair(resourceName, "share_arn", principalAssociationResourceName, "resource_share_arn"),
testAccMatchResourceAttrRegionalARNAccountID(resourceName, "invitation_arn", "ram", `\d{12}`, regexp.MustCompile(fmt.Sprintf("resource-share-invitation/%s$", uuidRegexPattern))),
resource.TestMatchResourceAttr(resourceName, "share_id", regexp.MustCompile(fmt.Sprintf(`^rs-%s$`, uuidRegexPattern))),
resource.TestCheckResourceAttr(resourceName, "status", ram.ResourceShareStatusActive),
testAccCheckResourceAttrAccountID(resourceName, "receiver_account_id"),
resource.TestMatchResourceAttr(resourceName, "sender_account_id", regexp.MustCompile(`\d{12}`)),
resource.TestCheckResourceAttr(resourceName, "share_name", rName),
resource.TestCheckResourceAttr(resourceName, "resources.%", "0"),
),
},
{
Config: testAccAwsRamResourceShareAccepterResourceAssociation(rName),
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckAwsRamResourceShareAccepterDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).ramconn

Expand Down Expand Up @@ -158,3 +197,75 @@ resource "aws_ram_principal_association" "test" {
data "aws_caller_identity" "receiver" {}
`, rName)
}

func testAccAwsRamResourceShareAccepterResourceAssociation(rName string) string {
return composeConfig(testAccAwsRamResourceShareAccepterBasic(rName), fmt.Sprintf(`
resource "aws_ram_resource_association" "test" {
provider = "awsalternate"

resource_arn = aws_codebuild_project.test.arn
resource_share_arn = aws_ram_resource_share.test.arn
}

resource "aws_codebuild_project" "test" {
provider = "awsalternate"

name = %[1]q
service_role = aws_iam_role.test.arn

artifacts {
type = "NO_ARTIFACTS"
}

environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "2"
type = "LINUX_CONTAINER"
}

source {
type = "GITHUB"
location = "https://github.com/hashicorp/packer.git"
}
}

data "aws_partition" "current" {}

resource "aws_iam_role" "test" {
provider = "awsalternate"

name = %[1]q

assume_role_policy = jsonencode({
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "codebuild.${data.aws_partition.current.dns_suffix}"
}
}]
Version = "2012-10-17"
})
}

resource "aws_iam_role_policy" "test" {
provider = "awsalternate"

name = %[1]q
role = aws_iam_role.test.name

policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Resource = ["*"]
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
}]
})
}
`, rName))
}