From d9261c7c04609fd4826bd47d8f119c8af88467d0 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 9 Apr 2019 16:02:17 -0400 Subject: [PATCH 1/6] r/ram_resource_share_accepter: New resource --- aws/provider.go | 1 + ...esource_aws_ram_resource_share_accepter.go | 163 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 aws/resource_aws_ram_resource_share_accepter.go diff --git a/aws/provider.go b/aws/provider.go index 93966053b04..65821f6e1d7 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -633,6 +633,7 @@ func Provider() terraform.ResourceProvider { "aws_ram_principal_association": resourceAwsRamPrincipalAssociation(), "aws_ram_resource_association": resourceAwsRamResourceAssociation(), "aws_ram_resource_share": resourceAwsRamResourceShare(), + "aws_ram_resource_share_accepter": resourceAwsRamResourceShareAccepter(), "aws_rds_cluster": resourceAwsRDSCluster(), "aws_rds_cluster_endpoint": resourceAwsRDSClusterEndpoint(), "aws_rds_cluster_instance": resourceAwsRDSClusterInstance(), diff --git a/aws/resource_aws_ram_resource_share_accepter.go b/aws/resource_aws_ram_resource_share_accepter.go new file mode 100644 index 00000000000..93a069dbae6 --- /dev/null +++ b/aws/resource_aws_ram_resource_share_accepter.go @@ -0,0 +1,163 @@ +package aws + +import ( + "fmt" + "log" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ram" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" +) + +func resourceAwsRamResourceShareAccepter() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsRamResourceShareAccepterCreate, + Read: resourceAwsRamResourceShareAccepterRead, + Delete: resourceAwsRamResourceShareAccepterDelete, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(5 * time.Minute), + Delete: schema.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArn, + }, + + "status": { + Type: schema.TypeString, + Computed: true, + }, + + "receiver_account_id": { + Type: schema.TypeString, + Computed: true, + }, + + "sender_account_id": { + Type: schema.TypeString, + Computed: true, + }, + + "share_arn": { + Type: schema.TypeString, + Computed: true, + }, + + "share_name": { + Type: schema.TypeString, + Computed: true, + }, + + "client_token": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 64), + }, + }, + } +} + +func resourceAwsRamResourceShareAccepterCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ramconn + + requestInput := &ram.AcceptResourceShareInvitationInput{ + ResourceShareInvitationArn: aws.String(d.Get("arn").(string)), + } + + if v, ok := d.GetOk("client_token"); ok { + requestInput.ClientToken = aws.String(v.(string)) + } + + log.Println("[DEBUG] Accept RAM resource share invitation request:", requestInput) + requestOutput, err := conn.AcceptResourceShareInvitation(requestInput) + if err != nil { + return fmt.Errorf("Error accepting RAM resource share invitation: %s", err) + } + + d.SetId(aws.StringValue(requestOutput.ResourceShareInvitation.ResourceShareInvitationArn)) + + stateConf := &resource.StateChangeConf{ + Pending: []string{ram.ResourceShareInvitationStatusPending}, + Target: []string{ram.ResourceShareInvitationStatusAccepted}, + Refresh: resourceAwsRamResourceShareAccepterStateRefreshFunc(conn, d.Id()), + Timeout: d.Timeout(schema.TimeoutCreate), + } + + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for RAM resource share invitation (%s) state: %s", d.Id(), err) + } + + return resourceAwsRamResourceShareAccepterRead(d, meta) +} + +func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ramconn + + request := &ram.GetResourceShareInvitationsInput{ + ResourceShareInvitationArns: []*string{aws.String(d.Id())}, + } + + output, err := conn.GetResourceShareInvitations(request) + if err != nil { + if isAWSErr(err, ram.ErrCodeUnknownResourceException, "") { + log.Printf("[WARN] No RAM resource share invitation by ARN (%s) found, removing from state", d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("Error reading RAM resource share invitation %s: %s", d.Id(), err) + } + + if len(output.ResourceShareInvitations) == 0 { + log.Printf("[WARN] No RAM resource share invitation by ARN (%s) found, removing from state", d.Id()) + d.SetId("") + return nil + } + + invitation := output.ResourceShareInvitations[0] + + d.Set("status", invitation.Status) + d.Set("receiver_account_id", invitation.ReceiverAccountId) + d.Set("sender_account_id", invitation.SenderAccountId) + d.Set("share_arn", invitation.ResourceShareArn) + d.Set("share_name", invitation.ResourceShareName) + + return nil +} + +func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[WARN] Will not delete resource share invitation. Terraform will remove this invitation from the state file. However, resources may remain.") + return nil +} + +func resourceAwsRamResourceShareAccepterStateRefreshFunc(conn *ram.RAM, invitationArn string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + request := &ram.GetResourceShareInvitationsInput{ + ResourceShareInvitationArns: []*string{aws.String(invitationArn)}, + } + + output, err := conn.GetResourceShareInvitations(request) + + if err != nil { + return nil, "Unable to get resource share invitations", err + } + + if len(output.ResourceShareInvitations) == 0 { + return nil, "Resource share invitation not found", nil + } + + invitation := output.ResourceShareInvitations[0] + + return invitation, aws.StringValue(invitation.Status), nil + } +} From d3a5fca45951fd25bef9167802790a6da4a208f1 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Fri, 17 May 2019 14:43:43 -0400 Subject: [PATCH 2/6] Add arguments, delete to disassociate --- ...esource_aws_ram_resource_share_accepter.go | 196 +++++++++++++++--- 1 file changed, 169 insertions(+), 27 deletions(-) diff --git a/aws/resource_aws_ram_resource_share_accepter.go b/aws/resource_aws_ram_resource_share_accepter.go index 93a069dbae6..9287282dd7c 100644 --- a/aws/resource_aws_ram_resource_share_accepter.go +++ b/aws/resource_aws_ram_resource_share_accepter.go @@ -3,14 +3,15 @@ package aws import ( "fmt" "log" + "strings" "time" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ram" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/helper/validation" ) func resourceAwsRamResourceShareAccepter() *schema.Resource { @@ -19,35 +20,48 @@ func resourceAwsRamResourceShareAccepter() *schema.Resource { Read: resourceAwsRamResourceShareAccepterRead, Delete: resourceAwsRamResourceShareAccepterDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(5 * time.Minute), Delete: schema.DefaultTimeout(5 * time.Minute), }, Schema: map[string]*schema.Schema{ - "arn": { + "invitation_arn": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, + Computed: true, ValidateFunc: validateArn, }, - "status": { + "share_arn": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + ValidateFunc: validateArn, + }, + + "share_id": { Type: schema.TypeString, Computed: true, }, - "receiver_account_id": { + "status": { Type: schema.TypeString, Computed: true, }, - "sender_account_id": { + "receiver_account_id": { Type: schema.TypeString, Computed: true, }, - "share_arn": { + "sender_account_id": { Type: schema.TypeString, Computed: true, }, @@ -57,11 +71,12 @@ func resourceAwsRamResourceShareAccepter() *schema.Resource { Computed: true, }, - "client_token": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - ValidateFunc: validation.StringLenBetween(1, 64), + "resources": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, }, } @@ -70,21 +85,31 @@ func resourceAwsRamResourceShareAccepter() *schema.Resource { func resourceAwsRamResourceShareAccepterCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ramconn - requestInput := &ram.AcceptResourceShareInvitationInput{ - ResourceShareInvitationArn: aws.String(d.Get("arn").(string)), + in := &ram.AcceptResourceShareInvitationInput{ + ClientToken: aws.String(resource.UniqueId()), } - if v, ok := d.GetOk("client_token"); ok { - requestInput.ClientToken = aws.String(v.(string)) + if v, ok := d.GetOk("invitation_arn"); ok { + in.ResourceShareInvitationArn = aws.String(v.(string)) + } else if v, ok := d.GetOk("share_arn"); ok { + // need to find invitation arn + invitationARN, err := resourceAwsRamResourceShareGetInvitationARN(conn, v.(string)) + if err != nil { + return err + } + + in.ResourceShareInvitationArn = aws.String(invitationARN) + } else { + return fmt.Errorf("Either an invitation ARN or share ARN are required") } - log.Println("[DEBUG] Accept RAM resource share invitation request:", requestInput) - requestOutput, err := conn.AcceptResourceShareInvitation(requestInput) + log.Printf("[DEBUG] Accept RAM resource share invitation request: %s", in) + out, err := conn.AcceptResourceShareInvitation(in) if err != nil { return fmt.Errorf("Error accepting RAM resource share invitation: %s", err) } - d.SetId(aws.StringValue(requestOutput.ResourceShareInvitation.ResourceShareInvitationArn)) + d.SetId(aws.StringValue(out.ResourceShareInvitation.ResourceShareInvitationArn)) stateConf := &resource.StateChangeConf{ Pending: []string{ram.ResourceShareInvitationStatusPending}, @@ -95,7 +120,7 @@ func resourceAwsRamResourceShareAccepterCreate(d *schema.ResourceData, meta inte _, err = stateConf.WaitForState() if err != nil { - return fmt.Errorf("Error waiting for RAM resource share invitation (%s) state: %s", d.Id(), err) + return fmt.Errorf("Error waiting for RAM resource share (%s) state: %s", d.Id(), err) } return resourceAwsRamResourceShareAccepterRead(d, meta) @@ -108,7 +133,7 @@ func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interf ResourceShareInvitationArns: []*string{aws.String(d.Id())}, } - output, err := conn.GetResourceShareInvitations(request) + out, err := conn.GetResourceShareInvitations(request) if err != nil { if isAWSErr(err, ram.ErrCodeUnknownResourceException, "") { log.Printf("[WARN] No RAM resource share invitation by ARN (%s) found, removing from state", d.Id()) @@ -118,27 +143,140 @@ func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interf return fmt.Errorf("Error reading RAM resource share invitation %s: %s", d.Id(), err) } - if len(output.ResourceShareInvitations) == 0 { + if len(out.ResourceShareInvitations) == 0 { log.Printf("[WARN] No RAM resource share invitation by ARN (%s) found, removing from state", d.Id()) d.SetId("") return nil } - invitation := output.ResourceShareInvitations[0] + invitation := out.ResourceShareInvitations[0] d.Set("status", invitation.Status) d.Set("receiver_account_id", invitation.ReceiverAccountId) d.Set("sender_account_id", invitation.SenderAccountId) d.Set("share_arn", invitation.ResourceShareArn) + d.Set("invitation_arn", invitation.ResourceShareInvitationArn) + d.Set("share_id", resourceAwsRamResourceShareGetIDFromARN(aws.StringValue(invitation.ResourceShareArn))) d.Set("share_name", invitation.ResourceShareName) + var nextToken string + var resourceARNs []*string + for { + listInput := &ram.ListResourcesInput{ + MaxResults: aws.Int64(int64(500)), + ResourceOwner: aws.String(ram.ResourceOwnerOtherAccounts), + ResourceShareArns: aws.StringSlice([]string{aws.StringValue(invitation.ResourceShareArn)}), + Principal: invitation.SenderAccountId, + } + + if nextToken != "" { + listInput.NextToken = aws.String(nextToken) + } + out, err := conn.ListResources(listInput) + if err != nil { + return fmt.Errorf("could not list share resources: %s", err) + } + for _, resource := range out.Resources { + resourceARNs = append(resourceARNs, resource.Arn) + } + + if out.NextToken == nil { + break + } + nextToken = aws.StringValue(out.NextToken) + } + + if err := d.Set("resources", flattenStringList(resourceARNs)); err != nil { + return fmt.Errorf("unable to set resources: %s", err) + } + return nil } +/* func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta interface{}) error { - log.Printf("[WARN] Will not delete resource share invitation. Terraform will remove this invitation from the state file. However, resources may remain.") + d.SetId("") + log.Printf("[WARN] Will not delete resource share invitation. Terraform will remove this invitation accepter from the state file. However, resources may remain.") return nil } +*/ + +func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ramconn + + v, ok := d.GetOk("share_arn") + if !ok { + return fmt.Errorf("The share ARN is required to leave a resource share") + } + shareARN := v.(string) + + v, ok = d.GetOk("receiver_account_id") + if !ok { + return fmt.Errorf("The receiver account ID is required to leave a resource share") + } + receiverID := v.(string) + + in := &ram.DisassociateResourceShareInput{ + ClientToken: aws.String(resource.UniqueId()), + ResourceShareArn: aws.String(shareARN), + Principals: []*string{aws.String(receiverID)}, + } + log.Printf("[DEBUG] Leaving RAM resource share request: %s", in) + _, err := conn.DisassociateResourceShare(in) + if err != nil { + return fmt.Errorf("Error leaving RAM resource share: %s", err) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{ram.ResourceShareAssociationStatusAssociated}, + Target: []string{ram.ResourceShareAssociationStatusDisassociated}, + Refresh: resourceAwsRamResourceShareStateRefreshFunc(conn, shareARN), + Timeout: d.Timeout(schema.TimeoutCreate), + } + + if _, err := stateConf.WaitForState(); err != nil { + if awserr, ok := err.(awserr.Error); ok { + switch awserr.Code() { + case ram.ErrCodeUnknownResourceException: + // what we want + d.SetId("") + return nil + } + } + return fmt.Errorf("Error waiting for RAM resource share (%s) state: %s", d.Id(), err) + } + + return nil +} + +func resourceAwsRamResourceShareGetInvitationARN(conn *ram.RAM, resourceShareARN string) (string, error) { + var nextToken string + for { + input := &ram.GetResourceShareInvitationsInput{ + MaxResults: aws.Int64(int64(500)), + ResourceShareArns: aws.StringSlice([]string{resourceShareARN}), + } + if nextToken != "" { + input.NextToken = aws.String(nextToken) + } + out, err := conn.GetResourceShareInvitations(input) + if err != nil { + return "", err + } + for _, invitation := range out.ResourceShareInvitations { + if aws.StringValue(invitation.Status) == ram.ResourceShareInvitationStatusPending { + return aws.StringValue(invitation.ResourceShareInvitationArn), nil + } + } + + if out.NextToken == nil { + break + } + nextToken = aws.StringValue(out.NextToken) + } + + return "", fmt.Errorf("Unable to find a pending invitation for resource share %s", resourceShareARN) +} func resourceAwsRamResourceShareAccepterStateRefreshFunc(conn *ram.RAM, invitationArn string) resource.StateRefreshFunc { return func() (interface{}, string, error) { @@ -146,18 +284,22 @@ func resourceAwsRamResourceShareAccepterStateRefreshFunc(conn *ram.RAM, invitati ResourceShareInvitationArns: []*string{aws.String(invitationArn)}, } - output, err := conn.GetResourceShareInvitations(request) + out, err := conn.GetResourceShareInvitations(request) if err != nil { return nil, "Unable to get resource share invitations", err } - if len(output.ResourceShareInvitations) == 0 { + if len(out.ResourceShareInvitations) == 0 { return nil, "Resource share invitation not found", nil } - invitation := output.ResourceShareInvitations[0] + invitation := out.ResourceShareInvitations[0] return invitation, aws.StringValue(invitation.Status), nil } } + +func resourceAwsRamResourceShareGetIDFromARN(arn string) string { + return strings.Replace(arn[strings.LastIndex(arn, ":")+1:], "resource-share/", "rs-", -1) +} From 6c92bb4d8eb9748664057d65e886eabc55367091 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Fri, 17 May 2019 17:09:40 -0400 Subject: [PATCH 3/6] Add docs --- website/aws.erb | 3 + .../r/ram_resource_share_accepter.markdown | 80 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 website/docs/r/ram_resource_share_accepter.markdown diff --git a/website/aws.erb b/website/aws.erb index f8ae727771d..2bb589fd6ee 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -324,6 +324,9 @@ +
  • + aws_ram_resource_share_accepter +
  • diff --git a/website/docs/r/ram_resource_share_accepter.markdown b/website/docs/r/ram_resource_share_accepter.markdown new file mode 100644 index 00000000000..faade61b3b4 --- /dev/null +++ b/website/docs/r/ram_resource_share_accepter.markdown @@ -0,0 +1,80 @@ +--- +layout: "aws" +page_title: "AWS: aws_ram_resource_share_accepter" +sidebar_current: "docs-aws-resource-ram-resource-share-accepter" +description: |- + Manages accepting a Resource Access Manager (RAM) Resource Share invitation. +--- + +# Resource: aws_ram_resource_share_accepter + +Manage accepting a Resource Access Manager (RAM) Resource Share invitation. From a _receiver_ AWS account, accept an invitation to share resources that were shared by a _sender_ AWS account. To create a resource share in the _sender_, see the [`aws_ram_resource_share` resource](/docs/providers/aws/r/ram_resource_share.html). + +~> **Note:** You can [`share resources`](https://docs.aws.amazon.com/ram/latest/userguide/getting-started-sharing.html) with Organizations, Organizational Units (OUs), AWS accounts, and accounts from outside of your Organization. + +## Example Usage + +This configuration provides an example of using multiple Terraform AWS providers to configure two different AWS accounts. In the _sender_ account, the configuration creates a `aws_ram_resource_share` and uses a data source in the _receiver_ account to create a `aws_ram_principal_assocation` resource with the _receiver's_ account ID. In the _receiver_ account, the configuration accepts the invitation to share resources with the `aws_ram_resource_share_accepter`. + +```hcl +provider "aws" { + profile = "profile2" +} + +provider "aws" { + alias = "alternate" + profile = "profile1" +} + +resource "aws_ram_resource_share" "sender_share" { + provider = "aws.alternate" + + name = "tf-test-resource-share" + allow_external_principals = true + + tags = { + Name = "tf-test-resource-share" + } +} + +resource "aws_ram_principal_association" "sender_invite" { + provider = "aws.alternate" + + principal = "${data.aws_caller_identity.receiver.account_id}" + resource_share_arn = "${aws_ram_resource_share.test.arn}" +} + +data "aws_caller_identity" "receiver" {} + +resource "aws_ram_resource_share_accepter" "receiver_accept" { + share_arn = "${aws_ram_principal_association.test.resource_share_arn}" +} +``` + +## Argument Reference + +The following arguments are supported: + +~> **Note:** One of either `share_arn` or `invitation_arn` is required. Using `share_arn` where multiple resources share invitations exist between the same _sender_ and _receiver_, may result in this resource selecting an unexpected invitation. In that case, use `invitation_arn`. + +* `share_arn` - (Optional) The ARN of the resource share. +* `invitation_arn` - (Optional) The ARN of the resource share invitation. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `share_id` - The ID of the resource share as displayed in the console. +* `status` - The status of the invitation (e.g., ACCEPTED, REJECTED). +* `receiver_account_id` - The account ID of the receiver account which accepts the invitation. +* `sender_account_id` - The account ID of the sender account which extends the invitation. +* `share_name` - The name of the resource share. +* `resources` - A list of the resource ARNs shared via the resource share. + +## Import + +Resource share accepters can be imported using the invitation ARN, e.g. + +``` +$ terraform import aws_ram_resource_share_accepter.example arn:aws:ram:us-east-1:123456789012:resource-share/c4b56393-e8d9-89d9-6dc9-883752de4767 +``` From f3dbef353231bd353657516bf1a8f6e69c60ab58 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 21 May 2019 20:00:19 -0400 Subject: [PATCH 4/6] Add acceptance test, remove comments, fix minor issue --- ...esource_aws_ram_resource_share_accepter.go | 8 -- ...ce_aws_ram_resource_share_accepter_test.go | 128 ++++++++++++++++++ 2 files changed, 128 insertions(+), 8 deletions(-) create mode 100644 aws/resource_aws_ram_resource_share_accepter_test.go diff --git a/aws/resource_aws_ram_resource_share_accepter.go b/aws/resource_aws_ram_resource_share_accepter.go index 9287282dd7c..4f65e1dc5f8 100644 --- a/aws/resource_aws_ram_resource_share_accepter.go +++ b/aws/resource_aws_ram_resource_share_accepter.go @@ -193,14 +193,6 @@ func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interf return nil } -/* -func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta interface{}) error { - d.SetId("") - log.Printf("[WARN] Will not delete resource share invitation. Terraform will remove this invitation accepter from the state file. However, resources may remain.") - return nil -} -*/ - func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ramconn diff --git a/aws/resource_aws_ram_resource_share_accepter_test.go b/aws/resource_aws_ram_resource_share_accepter_test.go new file mode 100644 index 00000000000..2269317abdf --- /dev/null +++ b/aws/resource_aws_ram_resource_share_accepter_test.go @@ -0,0 +1,128 @@ +package aws + +import ( + "fmt" + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ram" +) + +func TestAccAwsRamResourceShareAccepter_basic(t *testing.T) { + var providers []*schema.Provider + resourceName := "aws_ram_resource_share_accepter.test" + shareName := fmt.Sprintf("tf-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccAlternateAccountPreCheck(t) + }, + ProviderFactories: testAccProviderFactories(&providers), + CheckDestroy: testAccCheckAwsRamResourceShareAccepterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsRamResourceShareAccepterBasic(shareName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsRamResourceShareAccepterExists(resourceName), + resource.TestMatchResourceAttr(resourceName, "share_arn", regexp.MustCompile(`^arn\:aws\:ram\:.*resource-share/.+$`)), + resource.TestMatchResourceAttr(resourceName, "invitation_arn", regexp.MustCompile(`^arn\:aws\:ram\:.*resource-share-invitation/.+$`)), + resource.TestMatchResourceAttr(resourceName, "share_id", regexp.MustCompile(`^rs-.+$`)), + resource.TestCheckResourceAttr(resourceName, "status", ram.ResourceShareInvitationStatusAccepted), + resource.TestMatchResourceAttr(resourceName, "receiver_account_id", regexp.MustCompile(`\d{12}`)), + resource.TestMatchResourceAttr(resourceName, "sender_account_id", regexp.MustCompile(`\d{12}`)), + resource.TestCheckResourceAttr(resourceName, "share_name", shareName), + resource.TestCheckResourceAttr(resourceName, "resources.%", "0"), + ), + }, + { + Config: testAccAwsRamResourceShareAccepterBasic(shareName), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckAwsRamResourceShareAccepterDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).ramconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_ram_resource_share_accepter" { + continue + } + + request := &ram.GetResourceSharesInput{ + ResourceShareArns: []*string{aws.String(rs.Primary.Attributes["share_arn"])}, + ResourceOwner: aws.String(ram.ResourceOwnerOtherAccounts), + } + + resp, err := conn.GetResourceShares(request) + if err != nil { + if awserr, ok := err.(awserr.Error); ok { + switch awserr.Code() { + case ram.ErrCodeUnknownResourceException: + // good - it's gone + return nil + } + } + return fmt.Errorf("Error deleting RAM resource share: %s", err) + } + + if len(resp.ResourceShares) == 0 { + return nil + } + } + return fmt.Errorf("RAM resource share association found, should be destroyed") +} + +func testAccCheckAwsRamResourceShareAccepterExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + _, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + return nil + } +} + +func testAccAwsRamResourceShareAccepterBasic(shareName string) string { + return testAccAlternateAccountProviderConfig() + fmt.Sprintf(` +resource "aws_ram_resource_share" "test" { + provider = "aws.alternate" + + name = %q + allow_external_principals = true + + tags = { + Name = %q + } +} + +resource "aws_ram_principal_association" "test" { + provider = "aws.alternate" + + principal = "${data.aws_caller_identity.receiver.account_id}" + resource_share_arn = "${aws_ram_resource_share.test.arn}" + + depends_on = ["data.aws_caller_identity.receiver"] +} + +data "aws_caller_identity" "receiver" {} + +resource "aws_ram_resource_share_accepter" "test" { + share_arn = "${aws_ram_resource_share.test.arn}" + + depends_on = ["aws_ram_resource_share.test", "aws_ram_principal_association.test"] +} +`, shareName, shareName) +} From 1226a0a3cd00cbefba9db0543ba75f1414314155 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 13 Aug 2019 22:50:47 -0400 Subject: [PATCH 5/6] Adjust for better code --- ...esource_aws_ram_resource_share_accepter.go | 178 +++++++++--------- ...ce_aws_ram_resource_share_accepter_test.go | 48 ++--- 2 files changed, 110 insertions(+), 116 deletions(-) diff --git a/aws/resource_aws_ram_resource_share_accepter.go b/aws/resource_aws_ram_resource_share_accepter.go index 4f65e1dc5f8..61f59974d00 100644 --- a/aws/resource_aws_ram_resource_share_accepter.go +++ b/aws/resource_aws_ram_resource_share_accepter.go @@ -7,7 +7,6 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ram" "github.com/hashicorp/terraform/helper/resource" @@ -85,36 +84,42 @@ func resourceAwsRamResourceShareAccepter() *schema.Resource { func resourceAwsRamResourceShareAccepterCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ramconn - in := &ram.AcceptResourceShareInvitationInput{ + input := &ram.AcceptResourceShareInvitationInput{ ClientToken: aws.String(resource.UniqueId()), } - if v, ok := d.GetOk("invitation_arn"); ok { - in.ResourceShareInvitationArn = aws.String(v.(string)) - } else if v, ok := d.GetOk("share_arn"); ok { - // need to find invitation arn - invitationARN, err := resourceAwsRamResourceShareGetInvitationARN(conn, v.(string)) + if v, ok := d.GetOk("invitation_arn"); ok && v.(string) != "" { + input.ResourceShareInvitationArn = aws.String(v.(string)) + } else if v, ok := d.GetOk("share_arn"); ok && v.(string) != "" { + // need invitation arn + invitation, err := resourceAwsRamResourceShareGetInvitation(d, meta, v.(string), ram.ResourceShareInvitationStatusPending) if err != nil { return err } + if invitation == nil || aws.StringValue(invitation.ResourceShareInvitationArn) == "" { + return fmt.Errorf("No RAM resource share invitation by ARN (%s) found", v.(string)) + } - in.ResourceShareInvitationArn = aws.String(invitationARN) + input.ResourceShareInvitationArn = invitation.ResourceShareInvitationArn } else { return fmt.Errorf("Either an invitation ARN or share ARN are required") } - log.Printf("[DEBUG] Accept RAM resource share invitation request: %s", in) - out, err := conn.AcceptResourceShareInvitation(in) + log.Printf("[DEBUG] Accept RAM resource share invitation request: %s", input) + output, err := conn.AcceptResourceShareInvitation(input) if err != nil { return fmt.Errorf("Error accepting RAM resource share invitation: %s", err) } - d.SetId(aws.StringValue(out.ResourceShareInvitation.ResourceShareInvitationArn)) + d.SetId(aws.StringValue(output.ResourceShareInvitation.ResourceShareArn)) + d.Set("invitation_arn", output.ResourceShareInvitation.ResourceShareInvitationArn) stateConf := &resource.StateChangeConf{ Pending: []string{ram.ResourceShareInvitationStatusPending}, Target: []string{ram.ResourceShareInvitationStatusAccepted}, - Refresh: resourceAwsRamResourceShareAccepterStateRefreshFunc(conn, d.Id()), + Refresh: resourceAwsRamResourceShareAccepterStateRefreshFunc( + conn, + aws.StringValue(output.ResourceShareInvitation.ResourceShareInvitationArn)), Timeout: d.Timeout(schema.TimeoutCreate), } @@ -129,61 +134,44 @@ func resourceAwsRamResourceShareAccepterCreate(d *schema.ResourceData, meta inte func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ramconn - request := &ram.GetResourceShareInvitationsInput{ - ResourceShareInvitationArns: []*string{aws.String(d.Id())}, - } + invitation, err := resourceAwsRamResourceShareGetInvitation(d, meta, d.Id(), ram.ResourceShareInvitationStatusAccepted) - out, err := conn.GetResourceShareInvitations(request) - if err != nil { - if isAWSErr(err, ram.ErrCodeUnknownResourceException, "") { - log.Printf("[WARN] No RAM resource share invitation by ARN (%s) found, removing from state", d.Id()) - d.SetId("") - return nil - } - return fmt.Errorf("Error reading RAM resource share invitation %s: %s", d.Id(), err) - } - - if len(out.ResourceShareInvitations) == 0 { + if err == nil && invitation == nil { log.Printf("[WARN] No RAM resource share invitation by ARN (%s) found, removing from state", d.Id()) d.SetId("") return nil } - invitation := out.ResourceShareInvitations[0] + if err != nil { + return err + } d.Set("status", invitation.Status) d.Set("receiver_account_id", invitation.ReceiverAccountId) d.Set("sender_account_id", invitation.SenderAccountId) d.Set("share_arn", invitation.ResourceShareArn) d.Set("invitation_arn", invitation.ResourceShareInvitationArn) - d.Set("share_id", resourceAwsRamResourceShareGetIDFromARN(aws.StringValue(invitation.ResourceShareArn))) + d.Set("share_id", resourceAwsRamResourceShareGetIDFromARN(d.Id())) d.Set("share_name", invitation.ResourceShareName) - var nextToken string - var resourceARNs []*string - for { - listInput := &ram.ListResourcesInput{ - MaxResults: aws.Int64(int64(500)), - ResourceOwner: aws.String(ram.ResourceOwnerOtherAccounts), - ResourceShareArns: aws.StringSlice([]string{aws.StringValue(invitation.ResourceShareArn)}), - Principal: invitation.SenderAccountId, - } + listInput := &ram.ListResourcesInput{ + MaxResults: aws.Int64(int64(500)), + ResourceOwner: aws.String(ram.ResourceOwnerOtherAccounts), + ResourceShareArns: aws.StringSlice([]string{d.Id()}), + Principal: invitation.SenderAccountId, + } - if nextToken != "" { - listInput.NextToken = aws.String(nextToken) - } - out, err := conn.ListResources(listInput) - if err != nil { - return fmt.Errorf("could not list share resources: %s", err) - } - for _, resource := range out.Resources { + var resourceARNs []*string + err = conn.ListResourcesPages(listInput, func(page *ram.ListResourcesOutput, lastPage bool) bool { + for _, resource := range page.Resources { resourceARNs = append(resourceARNs, resource.Arn) } - if out.NextToken == nil { - break - } - nextToken = aws.StringValue(out.NextToken) + return !lastPage + }) + + if err != nil { + return fmt.Errorf("Error reading RAM resource share resources %s: %s", d.Id(), err) } if err := d.Set("resources", flattenStringList(resourceARNs)); err != nil { @@ -196,25 +184,19 @@ func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interf func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ramconn - v, ok := d.GetOk("share_arn") - if !ok { - return fmt.Errorf("The share ARN is required to leave a resource share") - } - shareARN := v.(string) - - v, ok = d.GetOk("receiver_account_id") + v, ok := d.GetOk("receiver_account_id") if !ok { return fmt.Errorf("The receiver account ID is required to leave a resource share") } receiverID := v.(string) - in := &ram.DisassociateResourceShareInput{ + input := &ram.DisassociateResourceShareInput{ ClientToken: aws.String(resource.UniqueId()), - ResourceShareArn: aws.String(shareARN), + ResourceShareArn: aws.String(d.Id()), Principals: []*string{aws.String(receiverID)}, } - log.Printf("[DEBUG] Leaving RAM resource share request: %s", in) - _, err := conn.DisassociateResourceShare(in) + log.Printf("[DEBUG] Leaving RAM resource share request: %s", input) + _, err := conn.DisassociateResourceShare(input) if err != nil { return fmt.Errorf("Error leaving RAM resource share: %s", err) } @@ -222,18 +204,14 @@ func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta inte stateConf := &resource.StateChangeConf{ Pending: []string{ram.ResourceShareAssociationStatusAssociated}, Target: []string{ram.ResourceShareAssociationStatusDisassociated}, - Refresh: resourceAwsRamResourceShareStateRefreshFunc(conn, shareARN), - Timeout: d.Timeout(schema.TimeoutCreate), + Refresh: resourceAwsRamResourceShareStateRefreshFunc(conn, d.Id()), + Timeout: d.Timeout(schema.TimeoutDelete), } if _, err := stateConf.WaitForState(); err != nil { - if awserr, ok := err.(awserr.Error); ok { - switch awserr.Code() { - case ram.ErrCodeUnknownResourceException: - // what we want - d.SetId("") - return nil - } + if isAWSErr(err, ram.ErrCodeUnknownResourceException, "") { + // what we want + return nil } return fmt.Errorf("Error waiting for RAM resource share (%s) state: %s", d.Id(), err) } @@ -241,33 +219,45 @@ func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta inte return nil } -func resourceAwsRamResourceShareGetInvitationARN(conn *ram.RAM, resourceShareARN string) (string, error) { - var nextToken string - for { - input := &ram.GetResourceShareInvitationsInput{ - MaxResults: aws.Int64(int64(500)), - ResourceShareArns: aws.StringSlice([]string{resourceShareARN}), - } - if nextToken != "" { - input.NextToken = aws.String(nextToken) - } - out, err := conn.GetResourceShareInvitations(input) - if err != nil { - return "", err - } - for _, invitation := range out.ResourceShareInvitations { - if aws.StringValue(invitation.Status) == ram.ResourceShareInvitationStatusPending { - return aws.StringValue(invitation.ResourceShareInvitationArn), nil +func resourceAwsRamResourceShareGetInvitation(d *schema.ResourceData, meta interface{}, resourceShareARN, status string) (*ram.ResourceShareInvitation, error) { + conn := meta.(*AWSClient).ramconn + + input := &ram.GetResourceShareInvitationsInput{ + ResourceShareArns: []*string{aws.String(resourceShareARN)}, + } + + invitationARN := d.Get("invitation_arn").(string) + if invitationARN != "" { + input.ResourceShareInvitationArns = []*string{aws.String(invitationARN)} + } + + var invitation *ram.ResourceShareInvitation + err := conn.GetResourceShareInvitationsPages(input, func(page *ram.GetResourceShareInvitationsOutput, lastPage bool) bool { + for _, rsi := range page.ResourceShareInvitations { + if aws.StringValue(rsi.Status) == status { + invitation = rsi + break } } - if out.NextToken == nil { - break - } - nextToken = aws.StringValue(out.NextToken) + return !lastPage + }) + + // if invitation not found with invitation ARN, try to find without + if invitation == nil && invitationARN != "" { + d.Set("invitation_arn", "") + return resourceAwsRamResourceShareGetInvitation(d, meta, resourceShareARN, status) + } + + if invitation == nil { + return nil, nil + } + + if err != nil { + return nil, fmt.Errorf("Error reading RAM resource share invitation %s: %s", resourceShareARN, err) } - return "", fmt.Errorf("Unable to find a pending invitation for resource share %s", resourceShareARN) + return invitation, nil } func resourceAwsRamResourceShareAccepterStateRefreshFunc(conn *ram.RAM, invitationArn string) resource.StateRefreshFunc { @@ -276,17 +266,17 @@ func resourceAwsRamResourceShareAccepterStateRefreshFunc(conn *ram.RAM, invitati ResourceShareInvitationArns: []*string{aws.String(invitationArn)}, } - out, err := conn.GetResourceShareInvitations(request) + output, err := conn.GetResourceShareInvitations(request) if err != nil { return nil, "Unable to get resource share invitations", err } - if len(out.ResourceShareInvitations) == 0 { + if len(output.ResourceShareInvitations) == 0 { return nil, "Resource share invitation not found", nil } - invitation := out.ResourceShareInvitations[0] + invitation := output.ResourceShareInvitations[0] return invitation, aws.StringValue(invitation.Status), nil } diff --git a/aws/resource_aws_ram_resource_share_accepter_test.go b/aws/resource_aws_ram_resource_share_accepter_test.go index 2269317abdf..0e7c50e8e81 100644 --- a/aws/resource_aws_ram_resource_share_accepter_test.go +++ b/aws/resource_aws_ram_resource_share_accepter_test.go @@ -5,7 +5,6 @@ import ( "regexp" "testing" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -60,35 +59,44 @@ func testAccCheckAwsRamResourceShareAccepterDestroy(s *terraform.State) error { continue } - request := &ram.GetResourceSharesInput{ + input := &ram.GetResourceSharesInput{ ResourceShareArns: []*string{aws.String(rs.Primary.Attributes["share_arn"])}, ResourceOwner: aws.String(ram.ResourceOwnerOtherAccounts), } - resp, err := conn.GetResourceShares(request) + output, err := conn.GetResourceShares(input) if err != nil { - if awserr, ok := err.(awserr.Error); ok { - switch awserr.Code() { - case ram.ErrCodeUnknownResourceException: - // good - it's gone - return nil - } + if isAWSErr(err, ram.ErrCodeUnknownResourceException, "") { + return nil } return fmt.Errorf("Error deleting RAM resource share: %s", err) } - if len(resp.ResourceShares) == 0 { + if len(output.ResourceShares) == 0 { return nil } } - return fmt.Errorf("RAM resource share association found, should be destroyed") + return fmt.Errorf("RAM resource share invitation found, should be destroyed") } func testAccCheckAwsRamResourceShareAccepterExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { - _, ok := s.RootModule().Resources[name] - if !ok { - return fmt.Errorf("Not found: %s", name) + rs, ok := s.RootModule().Resources[name] + + if !ok || rs.Type != "aws_ram_resource_share_accepter" { + return fmt.Errorf("RAM resource share invitation not found: %s", name) + } + + conn := testAccProvider.Meta().(*AWSClient).ramconn + + input := &ram.GetResourceSharesInput{ + ResourceShareArns: []*string{aws.String(rs.Primary.Attributes["share_arn"])}, + ResourceOwner: aws.String(ram.ResourceOwnerOtherAccounts), + } + + output, err := conn.GetResourceShares(input) + if err != nil || len(output.ResourceShares) == 0 { + return fmt.Errorf("Error finding RAM resource share: %s", err) } return nil @@ -100,11 +108,11 @@ func testAccAwsRamResourceShareAccepterBasic(shareName string) string { resource "aws_ram_resource_share" "test" { provider = "aws.alternate" - name = %q + name = %[1]q allow_external_principals = true tags = { - Name = %q + Name = %[1]q } } @@ -113,16 +121,12 @@ resource "aws_ram_principal_association" "test" { principal = "${data.aws_caller_identity.receiver.account_id}" resource_share_arn = "${aws_ram_resource_share.test.arn}" - - depends_on = ["data.aws_caller_identity.receiver"] } data "aws_caller_identity" "receiver" {} resource "aws_ram_resource_share_accepter" "test" { - share_arn = "${aws_ram_resource_share.test.arn}" - - depends_on = ["aws_ram_resource_share.test", "aws_ram_principal_association.test"] + share_arn = "${aws_ram_principal_association.test.resource_share_arn}" } -`, shareName, shareName) +`, shareName) } From 8525f6d2e0d97914eb44354550f891b57cdd0388 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Wed, 14 Aug 2019 00:03:41 -0400 Subject: [PATCH 6/6] Remove the invitation ARN as argument --- ...esource_aws_ram_resource_share_accepter.go | 77 ++++++++----------- .../r/ram_resource_share_accepter.markdown | 10 +-- 2 files changed, 34 insertions(+), 53 deletions(-) diff --git a/aws/resource_aws_ram_resource_share_accepter.go b/aws/resource_aws_ram_resource_share_accepter.go index 61f59974d00..7065174453c 100644 --- a/aws/resource_aws_ram_resource_share_accepter.go +++ b/aws/resource_aws_ram_resource_share_accepter.go @@ -29,20 +29,16 @@ func resourceAwsRamResourceShareAccepter() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "invitation_arn": { + "share_arn": { Type: schema.TypeString, - Optional: true, + Required: true, ForceNew: true, - Computed: true, ValidateFunc: validateArn, }, - "share_arn": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Computed: true, - ValidateFunc: validateArn, + "invitation_arn": { + Type: schema.TypeString, + Computed: true, }, "share_id": { @@ -84,35 +80,32 @@ func resourceAwsRamResourceShareAccepter() *schema.Resource { func resourceAwsRamResourceShareAccepterCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ramconn - input := &ram.AcceptResourceShareInvitationInput{ - ClientToken: aws.String(resource.UniqueId()), + shareARN := d.Get("share_arn").(string) + + // need invitation arn + invitation, err := resourceAwsRamResourceShareGetInvitation(conn, shareARN, ram.ResourceShareInvitationStatusPending) + + if err != nil { + return err } - if v, ok := d.GetOk("invitation_arn"); ok && v.(string) != "" { - input.ResourceShareInvitationArn = aws.String(v.(string)) - } else if v, ok := d.GetOk("share_arn"); ok && v.(string) != "" { - // need invitation arn - invitation, err := resourceAwsRamResourceShareGetInvitation(d, meta, v.(string), ram.ResourceShareInvitationStatusPending) - if err != nil { - return err - } - if invitation == nil || aws.StringValue(invitation.ResourceShareInvitationArn) == "" { - return fmt.Errorf("No RAM resource share invitation by ARN (%s) found", v.(string)) - } + if invitation == nil || aws.StringValue(invitation.ResourceShareInvitationArn) == "" { + return fmt.Errorf("No RAM resource share invitation by ARN (%s) found", shareARN) + } - input.ResourceShareInvitationArn = invitation.ResourceShareInvitationArn - } else { - return fmt.Errorf("Either an invitation ARN or share ARN are required") + input := &ram.AcceptResourceShareInvitationInput{ + ClientToken: aws.String(resource.UniqueId()), + ResourceShareInvitationArn: invitation.ResourceShareInvitationArn, } log.Printf("[DEBUG] Accept RAM resource share invitation request: %s", input) output, err := conn.AcceptResourceShareInvitation(input) + if err != nil { return fmt.Errorf("Error accepting RAM resource share invitation: %s", err) } - d.SetId(aws.StringValue(output.ResourceShareInvitation.ResourceShareArn)) - d.Set("invitation_arn", output.ResourceShareInvitation.ResourceShareInvitationArn) + d.SetId(shareARN) stateConf := &resource.StateChangeConf{ Pending: []string{ram.ResourceShareInvitationStatusPending}, @@ -124,6 +117,7 @@ func resourceAwsRamResourceShareAccepterCreate(d *schema.ResourceData, meta inte } _, err = stateConf.WaitForState() + if err != nil { return fmt.Errorf("Error waiting for RAM resource share (%s) state: %s", d.Id(), err) } @@ -134,7 +128,7 @@ func resourceAwsRamResourceShareAccepterCreate(d *schema.ResourceData, meta inte func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ramconn - invitation, err := resourceAwsRamResourceShareGetInvitation(d, meta, d.Id(), ram.ResourceShareInvitationStatusAccepted) + invitation, err := resourceAwsRamResourceShareGetInvitation(conn, d.Id(), ram.ResourceShareInvitationStatusAccepted) if err == nil && invitation == nil { log.Printf("[WARN] No RAM resource share invitation by ARN (%s) found, removing from state", d.Id()) @@ -184,19 +178,21 @@ func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interf func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ramconn - v, ok := d.GetOk("receiver_account_id") - if !ok { + receiverAccountID := d.Get("receiver_account_id").(string) + + if receiverAccountID == "" { return fmt.Errorf("The receiver account ID is required to leave a resource share") } - receiverID := v.(string) input := &ram.DisassociateResourceShareInput{ ClientToken: aws.String(resource.UniqueId()), ResourceShareArn: aws.String(d.Id()), - Principals: []*string{aws.String(receiverID)}, + Principals: []*string{aws.String(receiverAccountID)}, } - log.Printf("[DEBUG] Leaving RAM resource share request: %s", input) + log.Printf("[DEBUG] Leave RAM resource share request: %s", input) + _, err := conn.DisassociateResourceShare(input) + if err != nil { return fmt.Errorf("Error leaving RAM resource share: %s", err) } @@ -219,18 +215,11 @@ func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta inte return nil } -func resourceAwsRamResourceShareGetInvitation(d *schema.ResourceData, meta interface{}, resourceShareARN, status string) (*ram.ResourceShareInvitation, error) { - conn := meta.(*AWSClient).ramconn - +func resourceAwsRamResourceShareGetInvitation(conn *ram.RAM, resourceShareARN, status string) (*ram.ResourceShareInvitation, error) { input := &ram.GetResourceShareInvitationsInput{ ResourceShareArns: []*string{aws.String(resourceShareARN)}, } - invitationARN := d.Get("invitation_arn").(string) - if invitationARN != "" { - input.ResourceShareInvitationArns = []*string{aws.String(invitationARN)} - } - var invitation *ram.ResourceShareInvitation err := conn.GetResourceShareInvitationsPages(input, func(page *ram.GetResourceShareInvitationsOutput, lastPage bool) bool { for _, rsi := range page.ResourceShareInvitations { @@ -243,12 +232,6 @@ func resourceAwsRamResourceShareGetInvitation(d *schema.ResourceData, meta inter return !lastPage }) - // if invitation not found with invitation ARN, try to find without - if invitation == nil && invitationARN != "" { - d.Set("invitation_arn", "") - return resourceAwsRamResourceShareGetInvitation(d, meta, resourceShareARN, status) - } - if invitation == nil { return nil, nil } diff --git a/website/docs/r/ram_resource_share_accepter.markdown b/website/docs/r/ram_resource_share_accepter.markdown index faade61b3b4..92b9ce0a476 100644 --- a/website/docs/r/ram_resource_share_accepter.markdown +++ b/website/docs/r/ram_resource_share_accepter.markdown @@ -14,7 +14,7 @@ Manage accepting a Resource Access Manager (RAM) Resource Share invitation. From ## Example Usage -This configuration provides an example of using multiple Terraform AWS providers to configure two different AWS accounts. In the _sender_ account, the configuration creates a `aws_ram_resource_share` and uses a data source in the _receiver_ account to create a `aws_ram_principal_assocation` resource with the _receiver's_ account ID. In the _receiver_ account, the configuration accepts the invitation to share resources with the `aws_ram_resource_share_accepter`. +This configuration provides an example of using multiple Terraform AWS providers to configure two different AWS accounts. In the _sender_ account, the configuration creates a `aws_ram_resource_share` and uses a data source in the _receiver_ account to create a `aws_ram_principal_association` resource with the _receiver's_ account ID. In the _receiver_ account, the configuration accepts the invitation to share resources with the `aws_ram_resource_share_accepter`. ```hcl provider "aws" { @@ -55,15 +55,13 @@ resource "aws_ram_resource_share_accepter" "receiver_accept" { The following arguments are supported: -~> **Note:** One of either `share_arn` or `invitation_arn` is required. Using `share_arn` where multiple resources share invitations exist between the same _sender_ and _receiver_, may result in this resource selecting an unexpected invitation. In that case, use `invitation_arn`. - -* `share_arn` - (Optional) The ARN of the resource share. -* `invitation_arn` - (Optional) The ARN of the resource share invitation. +* `share_arn` - (Required) The ARN of the resource share. ## Attributes Reference In addition to all arguments above, the following attributes are exported: +* `invitation_arn` - The ARN of the resource share invitation. * `share_id` - The ID of the resource share as displayed in the console. * `status` - The status of the invitation (e.g., ACCEPTED, REJECTED). * `receiver_account_id` - The account ID of the receiver account which accepts the invitation. @@ -73,7 +71,7 @@ In addition to all arguments above, the following attributes are exported: ## Import -Resource share accepters can be imported using the invitation ARN, e.g. +Resource share accepters can be imported using the resource share ARN, e.g. ``` $ terraform import aws_ram_resource_share_accepter.example arn:aws:ram:us-east-1:123456789012:resource-share/c4b56393-e8d9-89d9-6dc9-883752de4767