From a57857eba4176910f4c2915c681324508bff00ab Mon Sep 17 00:00:00 2001 From: Dmitry Shevchuk Date: Fri, 23 Apr 2021 16:51:56 +0300 Subject: [PATCH 01/11] Add resource aws_vpc_endpoint_connection_accepter --- resource_aws_vpc_endpoint_service_accepter.go | 177 ++++++++++++++ ..._aws_vpc_endpoint_service_accepter_test.go | 227 ++++++++++++++++++ 2 files changed, 404 insertions(+) create mode 100644 resource_aws_vpc_endpoint_service_accepter.go create mode 100644 resource_aws_vpc_endpoint_service_accepter_test.go diff --git a/resource_aws_vpc_endpoint_service_accepter.go b/resource_aws_vpc_endpoint_service_accepter.go new file mode 100644 index 00000000000..0506cb5f1ac --- /dev/null +++ b/resource_aws_vpc_endpoint_service_accepter.go @@ -0,0 +1,177 @@ +package aws + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceAwsVpcEndpointConnectionAccepter() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsVpcEndpointConnectionAccepterCreate, + Read: resourceAwsVpcEndpointConnectionAccepterRead, + Delete: resourceAwsVpcEndpointConnectionAccepterDelete, + + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + svcID, vpceID := parseVPCEndpointConnectionAccepterID(d.Id()) + + d.Set("service_id", svcID) + d.Set("endpoint_id", vpceID) + + return []*schema.ResourceData{d}, nil + }, + }, + + Schema: map[string]*schema.Schema{ + "service_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "endpoint_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "state": { + Type: schema.TypeString, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceAwsVpcEndpointConnectionAccepterCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + svcID := d.Get("service_id").(string) + vpceID := d.Get("endpoint_id").(string) + + input := &ec2.AcceptVpcEndpointConnectionsInput{ + ServiceId: aws.String(svcID), + VpcEndpointIds: aws.StringSlice([]string{vpceID}), + } + + log.Printf("[DEBUG] Accepting VPC Endpoint Connection: %#v", input) + _, err := conn.AcceptVpcEndpointConnections(input) + if err != nil { + return fmt.Errorf("error accepting VPC Endpoint Connection: %s", err.Error()) + } + + d.SetId(makeVPCEndpointConnectionAccepterID(svcID, vpceID)) + + stateConf := &resource.StateChangeConf{ + Pending: []string{"pendingAcceptance", "pending"}, + Target: []string{"available"}, + Refresh: vpcEndpointConnectionRefresh(conn, svcID, vpceID), + Timeout: d.Timeout(schema.TimeoutCreate), + Delay: 5 * time.Second, + MinTimeout: 5 * time.Second, + } + + vpceConn, err := stateConf.WaitForStateContext(context.Background()) + if err != nil { + return fmt.Errorf("error waiting for VPC Endpoint (%s) to be accepted by VPC Endpoint Service (%s): %s", vpceID, svcID, err) + } + + d.Set("state", aws.StringValue(vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState)) + + return resourceAwsVpcEndpointConnectionAccepterRead(d, meta) +} + +func vpcEndpointConnectionRefresh(conn *ec2.EC2, svcID, vpceID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + log.Printf("[DEBUG] Reading VPC Endpoint Connections for VPC Endpoint Service (%s)", svcID) + + input := &ec2.DescribeVpcEndpointConnectionsInput{ + Filters: buildEC2AttributeFilterList(map[string]string{"service-id": svcID}), + } + + var vpceConn *ec2.VpcEndpointConnection + + paginator := func(page *ec2.DescribeVpcEndpointConnectionsOutput, lastPage bool) bool { + for _, c := range page.VpcEndpointConnections { + if aws.StringValue(c.VpcEndpointId) == vpceID { + log.Printf("[DEBUG] Found VPC Endpoint Connection from VPC Endpoint Service (%s) to VPC Endpoint (%s): %s", svcID, vpceID, *c) + vpceConn = c + return false + } + } + return !lastPage + } + + if err := conn.DescribeVpcEndpointConnectionsPages(input, paginator); err != nil { + return nil, "", err + } + + if vpceConn == nil { + return nil, "", fmt.Errorf("VPC Endpoint Connection from VPC Endpoint Service (%s) to VPC Endpoint (%s) not found", svcID, vpceID) + } + + state := aws.StringValue(vpceConn.VpcEndpointState) + log.Printf("[DEBUG] state %s", state) + + // No point in retrying if the endpoint is in a failed state. + if state == "failed" { + return nil, state, fmt.Errorf("VPC Endpoint Connection state %q", state) + } + + return *vpceConn, state, nil + } +} + +func resourceAwsVpcEndpointConnectionAccepterRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + svcID, vpceID := parseVPCEndpointConnectionAccepterID(d.Id()) + + vpceConn, state, err := vpcEndpointConnectionRefresh(conn, svcID, vpceID)() + if err != nil && state != "failed" { + return fmt.Errorf("error reading VPC Endpoint Connection from VPC Endpoint Service (%s) to VPC Endpoint (%s): %s", svcID, vpceID, err) + } + + d.Set("state", aws.StringValue(vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState)) + + return nil +} + +func resourceAwsVpcEndpointConnectionAccepterDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + svcID, vpceID := parseVPCEndpointConnectionAccepterID(d.Id()) + + input := &ec2.RejectVpcEndpointConnectionsInput{ + ServiceId: aws.String(svcID), + VpcEndpointIds: aws.StringSlice([]string{vpceID}), + } + + if _, err := conn.RejectVpcEndpointConnections(input); err != nil { + return fmt.Errorf("error rejecting VPC Endpoint Connection from VPC Endpoint (%s) to VPC Endpoint Service (%s): %s", vpceID, svcID, err) + } + + return nil +} + +const vpcEndpointConnectionAccepterIDSeparator = "_" + +func makeVPCEndpointConnectionAccepterID(svcID, vpceID string) string { + return strings.Join([]string{svcID, vpceID}, vpcEndpointConnectionAccepterIDSeparator) +} + +func parseVPCEndpointConnectionAccepterID(vpceConnID string) (svcID string, vpceID string) { + split := strings.Split(vpceConnID, vpcEndpointConnectionAccepterIDSeparator) + + svcID = split[0] + vpceID = split[1] + + return +} diff --git a/resource_aws_vpc_endpoint_service_accepter_test.go b/resource_aws_vpc_endpoint_service_accepter_test.go new file mode 100644 index 00000000000..64f460f2f42 --- /dev/null +++ b/resource_aws_vpc_endpoint_service_accepter_test.go @@ -0,0 +1,227 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func TestAccVpcEndpointServiceAccepter_crossAccount(t *testing.T) { + var providers []*schema.Provider + resourceName := "aws_vpc_endpoint_connection_accepter.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccAlternateAccountPreCheck(t) + }, + ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), + ProviderFactories: testAccProviderFactoriesAlternate(&providers), + Steps: []resource.TestStep{ + { + Config: testAccVpcEndpointServiceAccepterConfig_crossAccount(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "state", "available"), + ), + }, + { + Config: testAccVpcEndpointServiceAccepterConfig_crossAccount(rName), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccVpcEndpointServiceAccepterConfig_crossAccount(rName string) string { + return testAccAlternateAccountProviderConfig() + fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} + +data "aws_availability_zones" "available" { + state = "available" + + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} + +resource "aws_subnet" "test1" { + vpc_id = aws_vpc.test.id + cidr_block = "10.0.1.0/24" + availability_zone = data.aws_availability_zones.available.names[0] + + tags = { + Name = %[1]q + } +} + +resource "aws_subnet" "test2" { + vpc_id = aws_vpc.test.id + cidr_block = "10.0.2.0/24" + availability_zone = data.aws_availability_zones.available.names[1] + + tags = { + Name = %[1]q + } +} + +resource "aws_subnet" "test3" { + vpc_id = aws_vpc.test.id + cidr_block = "10.0.3.0/24" + availability_zone = data.aws_availability_zones.available.names[2] + + tags = { + Name = %[1]q + } +} + +data "aws_caller_identity" "alternate" { + provider = "awsalternate" +} + +resource "aws_vpc" "test_alternate" { + provider = "awsalternate" + + cidr_block = "10.1.0.0/16" + + tags = { + Name = %[1]q + } +} + +data "aws_availability_zones" "alternate_available" { + provider = "awsalternate" + + state = "available" + + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} + +resource "aws_subnet" "test_alternate1" { + provider = "awsalternate" + + vpc_id = aws_vpc.test_alternate.id + cidr_block = "10.1.1.0/24" + availability_zone = data.aws_availability_zones.alternate_available.names[0] + + tags = { + Name = %[1]q + } +} + +resource "aws_subnet" "test_alternate2" { + provider = "awsalternate" + + vpc_id = aws_vpc.test_alternate.id + cidr_block = "10.1.2.0/24" + availability_zone = data.aws_availability_zones.alternate_available.names[1] + + tags = { + Name = %[1]q + } +} + +resource "aws_subnet" "test_alternate3" { + provider = "awsalternate" + + vpc_id = aws_vpc.test_alternate.id + cidr_block = "10.1.3.0/24" + availability_zone = data.aws_availability_zones.alternate_available.names[2] + + tags = { + Name = %[1]q + } +} + +data "aws_subnet_ids" "alternate_intersect" { + provider = "awsalternate" + + vpc_id = aws_vpc.test_alternate.id + + filter { + name = "availabilityZone" + values = aws_vpc_endpoint_service.test.availability_zones + } +} + +resource "aws_lb" "test" { + name = %[1]q + + subnets = [ + aws_subnet.test1.id, + aws_subnet.test2.id, + aws_subnet.test3.id, + ] + + load_balancer_type = "network" + internal = true + idle_timeout = 60 + enable_deletion_protection = false + + tags = { + Name = %[1]q + } +} + +resource "aws_vpc_endpoint_service" "test" { + acceptance_required = true + + network_load_balancer_arns = [ + aws_lb.test.id, + ] + + allowed_principals = [ + "arn:aws:iam::${data.aws_caller_identity.alternate.account_id}:root", + ] +} + +resource "aws_security_group" "test" { + provider = "awsalternate" + + vpc_id = aws_vpc.test_alternate.id + + tags = { + Name = %[1]q + } +} + +resource "aws_vpc_endpoint" "test" { + provider = "awsalternate" + + vpc_id = aws_vpc.test_alternate.id + service_name = aws_vpc_endpoint_service.test.service_name + subnet_ids = data.aws_subnet_ids.alternate_intersect.ids + vpc_endpoint_type = "Interface" + private_dns_enabled = false + + security_group_ids = [ + aws_security_group.test.id, + ] + + tags = { + Name = %[1]q + } +} + +resource "aws_vpc_endpoint_connection_accepter" "test" { + service_id = aws_vpc_endpoint_service.test.id + endpoint_id = aws_vpc_endpoint.test.id +} +`, rName) +} From ac99dfaa9636d4c788351c96587303a7215bdffc Mon Sep 17 00:00:00 2001 From: Dmitry Shevchuk Date: Fri, 23 Apr 2021 17:25:25 +0300 Subject: [PATCH 02/11] Add vpc_endpoint_connection_accepter website doc --- ...endpoint_connection_accepter.html.markdown | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 website/docs/r/vpc_endpoint_connection_accepter.html.markdown diff --git a/website/docs/r/vpc_endpoint_connection_accepter.html.markdown b/website/docs/r/vpc_endpoint_connection_accepter.html.markdown new file mode 100644 index 00000000000..8bb2c28535e --- /dev/null +++ b/website/docs/r/vpc_endpoint_connection_accepter.html.markdown @@ -0,0 +1,62 @@ +--- +subcategory: "VPC" +layout: "aws" +page_title: "AWS: aws_vpc_endpoint_connection_accepter" +description: |- + Provides a resource to accept a pending VPC Endpoint accept request to VPC Endpoint Service. +--- + +# Resource: aws_vpc_endpoint_connection_accepter + +Provides a resource to accept a pending VPC Endpoint Connection accept request to VPC Endpoint Service. + +## Example Usage + +### Accept cross-account request + +```terraform +resource "aws_vpc_endpoint_service" "example" { + acceptance_required = false + network_load_balancer_arns = [aws_lb.example.arn] +} + +resource "aws_vpc_endpoint" "example" { + provider = "aws.alternate" + + vpc_id = aws_vpc.test_alternate.id + service_name = aws_vpc_endpoint_service.test.service_name + vpc_endpoint_type = "Interface" + private_dns_enabled = false + + security_group_ids = [ + aws_security_group.test.id, + ] +} + +resource "aws_vpc_endpoint_connection_accepter" "example" { + service_id = aws_vpc_endpoint_service.example.id + endpoint_id = aws_vpc_endpoint.example.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `service_id` - (Required) AWS VPC Endpoint Service ID. +* `endpoint_id` - (Required) AWS VPC Endpoint ID. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the VPC Endpoint Connection. +* `state` - State of the VPC Endpoint Connection. + +## Import + +VPC Endpoint Services can be imported using ID of the connection, which is the `VPC Endpoint Service ID` and `VPC Endpoint ID` separated by underscore (`_`). e.g. + +``` +$ terraform import aws_vpc_endpoint_connection_accepter.foo vpce-010601a6db371e263_vpce-svc-0f97a19d3fa8220bc +``` From ddb81e765fbc720dc0d27f2a4ad4336d5583369b Mon Sep 17 00:00:00 2001 From: Dmitry Shevchuk Date: Fri, 23 Apr 2021 17:59:36 +0300 Subject: [PATCH 03/11] Add changelog Add CheckDestroy Rename previous files --- .changelog/19083.txt | 3 ++ ...ce_aws_vpc_endpoint_connection_accepter.go | 0 ...s_vpc_endpoint_connection_accepter_test.go | 42 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 .changelog/19083.txt rename resource_aws_vpc_endpoint_service_accepter.go => resource_aws_vpc_endpoint_connection_accepter.go (100%) rename resource_aws_vpc_endpoint_service_accepter_test.go => resource_aws_vpc_endpoint_connection_accepter_test.go (79%) diff --git a/.changelog/19083.txt b/.changelog/19083.txt new file mode 100644 index 00000000000..e8f189cb7ac --- /dev/null +++ b/.changelog/19083.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_vpc_endpoint_connection_accepter +``` diff --git a/resource_aws_vpc_endpoint_service_accepter.go b/resource_aws_vpc_endpoint_connection_accepter.go similarity index 100% rename from resource_aws_vpc_endpoint_service_accepter.go rename to resource_aws_vpc_endpoint_connection_accepter.go diff --git a/resource_aws_vpc_endpoint_service_accepter_test.go b/resource_aws_vpc_endpoint_connection_accepter_test.go similarity index 79% rename from resource_aws_vpc_endpoint_service_accepter_test.go rename to resource_aws_vpc_endpoint_connection_accepter_test.go index 64f460f2f42..2228f82ba93 100644 --- a/resource_aws_vpc_endpoint_service_accepter_test.go +++ b/resource_aws_vpc_endpoint_connection_accepter_test.go @@ -4,10 +4,12 @@ import ( "fmt" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "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" ) func TestAccVpcEndpointServiceAccepter_crossAccount(t *testing.T) { @@ -22,6 +24,7 @@ func TestAccVpcEndpointServiceAccepter_crossAccount(t *testing.T) { }, ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), ProviderFactories: testAccProviderFactoriesAlternate(&providers), + CheckDestroy: testAccCheckAwsVpcEndpointServiceAccepterDestroy, Steps: []resource.TestStep{ { Config: testAccVpcEndpointServiceAccepterConfig_crossAccount(rName), @@ -39,6 +42,45 @@ func TestAccVpcEndpointServiceAccepter_crossAccount(t *testing.T) { }) } +func testAccCheckAwsVpcEndpointServiceAccepterDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).ec2conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_vpc_endpoint_connection_accepter" { + continue + } + + svcID := rs.Primary.Attributes["service_id"] + vpceID := rs.Primary.Attributes["endpoint_id"] + + input := &ec2.DescribeVpcEndpointConnectionsInput{ + Filters: buildEC2AttributeFilterList(map[string]string{"service-id": svcID}), + } + + var foundAvailable bool + + paginator := func(page *ec2.DescribeVpcEndpointConnectionsOutput, lastPage bool) bool { + for _, c := range page.VpcEndpointConnections { + if aws.StringValue(c.VpcEndpointId) == vpceID && aws.StringValue(c.VpcEndpointState) == "available" { + foundAvailable = true + return false + } + } + return !lastPage + } + + if err := conn.DescribeVpcEndpointConnectionsPages(input, paginator); err != nil { + return err + } + + if foundAvailable { + return fmt.Errorf("AWS VPC Endpoint Service (%s) still has connection from AWS VPC Endpoint (%s) in available status", svcID, vpceID) + } + } + + return nil +} + func testAccVpcEndpointServiceAccepterConfig_crossAccount(rName string) string { return testAccAlternateAccountProviderConfig() + fmt.Sprintf(` resource "aws_vpc" "test" { From 51d718276ea089126a6a23afbe3e8dcc51b7d3c0 Mon Sep 17 00:00:00 2001 From: Dmitry Shevchuk Date: Mon, 26 Apr 2021 17:15:29 +0300 Subject: [PATCH 04/11] Fix issues found by linter --- resource_aws_vpc_endpoint_connection_accepter.go | 4 ++-- resource_aws_vpc_endpoint_connection_accepter_test.go | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/resource_aws_vpc_endpoint_connection_accepter.go b/resource_aws_vpc_endpoint_connection_accepter.go index 0506cb5f1ac..276670193bd 100644 --- a/resource_aws_vpc_endpoint_connection_accepter.go +++ b/resource_aws_vpc_endpoint_connection_accepter.go @@ -83,7 +83,7 @@ func resourceAwsVpcEndpointConnectionAccepterCreate(d *schema.ResourceData, meta return fmt.Errorf("error waiting for VPC Endpoint (%s) to be accepted by VPC Endpoint Service (%s): %s", vpceID, svcID, err) } - d.Set("state", aws.StringValue(vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState)) + d.Set("state", vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState) return resourceAwsVpcEndpointConnectionAccepterRead(d, meta) } @@ -139,7 +139,7 @@ func resourceAwsVpcEndpointConnectionAccepterRead(d *schema.ResourceData, meta i return fmt.Errorf("error reading VPC Endpoint Connection from VPC Endpoint Service (%s) to VPC Endpoint (%s): %s", svcID, vpceID, err) } - d.Set("state", aws.StringValue(vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState)) + d.Set("state", vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState) return nil } diff --git a/resource_aws_vpc_endpoint_connection_accepter_test.go b/resource_aws_vpc_endpoint_connection_accepter_test.go index 2228f82ba93..398893032ff 100644 --- a/resource_aws_vpc_endpoint_connection_accepter_test.go +++ b/resource_aws_vpc_endpoint_connection_accepter_test.go @@ -221,6 +221,8 @@ resource "aws_lb" "test" { } } +data "aws_partition" "current" {} + resource "aws_vpc_endpoint_service" "test" { acceptance_required = true @@ -229,7 +231,7 @@ resource "aws_vpc_endpoint_service" "test" { ] allowed_principals = [ - "arn:aws:iam::${data.aws_caller_identity.alternate.account_id}:root", + "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.alternate.account_id}:root", ] } From 0d4ff61a50d42027005b5d048d8a1f43daf070f7 Mon Sep 17 00:00:00 2001 From: Dmitry Shevchuk Date: Mon, 26 Apr 2021 18:43:39 +0300 Subject: [PATCH 05/11] Fix import resource ID typo --- website/docs/r/vpc_endpoint_connection_accepter.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/vpc_endpoint_connection_accepter.html.markdown b/website/docs/r/vpc_endpoint_connection_accepter.html.markdown index 8bb2c28535e..eb9e55adfdf 100644 --- a/website/docs/r/vpc_endpoint_connection_accepter.html.markdown +++ b/website/docs/r/vpc_endpoint_connection_accepter.html.markdown @@ -58,5 +58,5 @@ In addition to all arguments above, the following attributes are exported: VPC Endpoint Services can be imported using ID of the connection, which is the `VPC Endpoint Service ID` and `VPC Endpoint ID` separated by underscore (`_`). e.g. ``` -$ terraform import aws_vpc_endpoint_connection_accepter.foo vpce-010601a6db371e263_vpce-svc-0f97a19d3fa8220bc +$ terraform import aws_vpc_endpoint_connection_accepter.foo vpce-svc-0f97a19d3fa8220bc_vpce-010601a6db371e263 ``` From d0c27ad113b7c8eabdb05d5f11944e2bab34e0b5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Dec 2021 09:40:27 -0500 Subject: [PATCH 06/11] Move new files into per-service package. --- .../service/ec2/vpc_endpoint_connection_accepter.go | 0 .../service/ec2/vpc_endpoint_connection_accepter_test.go | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename resource_aws_vpc_endpoint_connection_accepter.go => internal/service/ec2/vpc_endpoint_connection_accepter.go (100%) rename resource_aws_vpc_endpoint_connection_accepter_test.go => internal/service/ec2/vpc_endpoint_connection_accepter_test.go (100%) diff --git a/resource_aws_vpc_endpoint_connection_accepter.go b/internal/service/ec2/vpc_endpoint_connection_accepter.go similarity index 100% rename from resource_aws_vpc_endpoint_connection_accepter.go rename to internal/service/ec2/vpc_endpoint_connection_accepter.go diff --git a/resource_aws_vpc_endpoint_connection_accepter_test.go b/internal/service/ec2/vpc_endpoint_connection_accepter_test.go similarity index 100% rename from resource_aws_vpc_endpoint_connection_accepter_test.go rename to internal/service/ec2/vpc_endpoint_connection_accepter_test.go From d364bdbbee23f0c358fa987896046f9864a499bc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Dec 2021 09:55:35 -0500 Subject: [PATCH 07/11] r/aws_vpc_endpoint_connection_accepter: Successful compilation after service-package restructuring. --- internal/provider/provider.go | 1 + .../ec2/vpc_endpoint_connection_accepter.go | 32 ++++++++--------- .../vpc_endpoint_connection_accepter_test.go | 35 ++++++++++--------- 3 files changed, 36 insertions(+), 32 deletions(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index eea3a4e4ae7..e8da1d1a67a 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1108,6 +1108,7 @@ func Provider() *schema.Provider { "aws_vpc_dhcp_options": ec2.ResourceVPCDHCPOptions(), "aws_vpc_dhcp_options_association": ec2.ResourceVPCDHCPOptionsAssociation(), "aws_vpc_endpoint": ec2.ResourceVPCEndpoint(), + "aws_vpc_endpoint_connection_accepter": ec2.ResourceVPCEndpointConnectionAccepter(), "aws_vpc_endpoint_connection_notification": ec2.ResourceVPCEndpointConnectionNotification(), "aws_vpc_endpoint_route_table_association": ec2.ResourceVPCEndpointRouteTableAssociation(), "aws_vpc_endpoint_service": ec2.ResourceVPCEndpointService(), diff --git a/internal/service/ec2/vpc_endpoint_connection_accepter.go b/internal/service/ec2/vpc_endpoint_connection_accepter.go index 276670193bd..5c68d52bc1b 100644 --- a/internal/service/ec2/vpc_endpoint_connection_accepter.go +++ b/internal/service/ec2/vpc_endpoint_connection_accepter.go @@ -1,4 +1,4 @@ -package aws +package ec2 import ( "context" @@ -11,13 +11,14 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" ) -func resourceAwsVpcEndpointConnectionAccepter() *schema.Resource { +func ResourceVPCEndpointConnectionAccepter() *schema.Resource { return &schema.Resource{ - Create: resourceAwsVpcEndpointConnectionAccepterCreate, - Read: resourceAwsVpcEndpointConnectionAccepterRead, - Delete: resourceAwsVpcEndpointConnectionAccepterDelete, + Create: resourceVPCEndpointConnectionAccepterCreate, + Read: resourceVPCEndpointConnectionAccepterRead, + Delete: resourceVPCEndpointConnectionAccepterDelete, Importer: &schema.ResourceImporter{ StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { @@ -31,12 +32,12 @@ func resourceAwsVpcEndpointConnectionAccepter() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "service_id": { + "endpoint_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "endpoint_id": { + "service_id": { Type: schema.TypeString, Required: true, ForceNew: true, @@ -44,14 +45,13 @@ func resourceAwsVpcEndpointConnectionAccepter() *schema.Resource { "state": { Type: schema.TypeString, Computed: true, - ForceNew: true, }, }, } } -func resourceAwsVpcEndpointConnectionAccepterCreate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).ec2conn +func resourceVPCEndpointConnectionAccepterCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).EC2Conn svcID := d.Get("service_id").(string) vpceID := d.Get("endpoint_id").(string) @@ -85,7 +85,7 @@ func resourceAwsVpcEndpointConnectionAccepterCreate(d *schema.ResourceData, meta d.Set("state", vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState) - return resourceAwsVpcEndpointConnectionAccepterRead(d, meta) + return resourceVPCEndpointConnectionAccepterRead(d, meta) } func vpcEndpointConnectionRefresh(conn *ec2.EC2, svcID, vpceID string) resource.StateRefreshFunc { @@ -93,7 +93,7 @@ func vpcEndpointConnectionRefresh(conn *ec2.EC2, svcID, vpceID string) resource. log.Printf("[DEBUG] Reading VPC Endpoint Connections for VPC Endpoint Service (%s)", svcID) input := &ec2.DescribeVpcEndpointConnectionsInput{ - Filters: buildEC2AttributeFilterList(map[string]string{"service-id": svcID}), + Filters: BuildAttributeFilterList(map[string]string{"service-id": svcID}), } var vpceConn *ec2.VpcEndpointConnection @@ -129,8 +129,8 @@ func vpcEndpointConnectionRefresh(conn *ec2.EC2, svcID, vpceID string) resource. } } -func resourceAwsVpcEndpointConnectionAccepterRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).ec2conn +func resourceVPCEndpointConnectionAccepterRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).EC2Conn svcID, vpceID := parseVPCEndpointConnectionAccepterID(d.Id()) @@ -144,8 +144,8 @@ func resourceAwsVpcEndpointConnectionAccepterRead(d *schema.ResourceData, meta i return nil } -func resourceAwsVpcEndpointConnectionAccepterDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).ec2conn +func resourceVPCEndpointConnectionAccepterDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).EC2Conn svcID, vpceID := parseVPCEndpointConnectionAccepterID(d.Id()) diff --git a/internal/service/ec2/vpc_endpoint_connection_accepter_test.go b/internal/service/ec2/vpc_endpoint_connection_accepter_test.go index 398893032ff..d4eb40ee73c 100644 --- a/internal/service/ec2/vpc_endpoint_connection_accepter_test.go +++ b/internal/service/ec2/vpc_endpoint_connection_accepter_test.go @@ -1,4 +1,4 @@ -package aws +package ec2_test import ( "fmt" @@ -6,34 +6,37 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "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/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" ) func TestAccVpcEndpointServiceAccepter_crossAccount(t *testing.T) { var providers []*schema.Provider resourceName := "aws_vpc_endpoint_connection_accepter.test" - rName := acctest.RandomWithPrefix("tf-acc-test") + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.Test(t, resource.TestCase{ PreCheck: func() { - testAccPreCheck(t) - testAccAlternateAccountPreCheck(t) + acctest.PreCheck(t) + acctest.PreCheckAlternateAccount(t) }, - ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), - ProviderFactories: testAccProviderFactoriesAlternate(&providers), - CheckDestroy: testAccCheckAwsVpcEndpointServiceAccepterDestroy, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + ProviderFactories: acctest.FactoriesAlternate(&providers), + CheckDestroy: testAccVPCEndpointServiceAccepterDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointServiceAccepterConfig_crossAccount(rName), + Config: testAccVPCEndpointServiceAccepterConfig_crossAccount(rName), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "state", "available"), ), }, { - Config: testAccVpcEndpointServiceAccepterConfig_crossAccount(rName), + Config: testAccVPCEndpointServiceAccepterConfig_crossAccount(rName), ResourceName: resourceName, ImportState: true, ImportStateVerify: true, @@ -42,8 +45,8 @@ func TestAccVpcEndpointServiceAccepter_crossAccount(t *testing.T) { }) } -func testAccCheckAwsVpcEndpointServiceAccepterDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).ec2conn +func testAccVPCEndpointServiceAccepterDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_vpc_endpoint_connection_accepter" { @@ -54,7 +57,7 @@ func testAccCheckAwsVpcEndpointServiceAccepterDestroy(s *terraform.State) error vpceID := rs.Primary.Attributes["endpoint_id"] input := &ec2.DescribeVpcEndpointConnectionsInput{ - Filters: buildEC2AttributeFilterList(map[string]string{"service-id": svcID}), + Filters: tfec2.BuildAttributeFilterList(map[string]string{"service-id": svcID}), } var foundAvailable bool @@ -81,8 +84,8 @@ func testAccCheckAwsVpcEndpointServiceAccepterDestroy(s *terraform.State) error return nil } -func testAccVpcEndpointServiceAccepterConfig_crossAccount(rName string) string { - return testAccAlternateAccountProviderConfig() + fmt.Sprintf(` +func testAccVPCEndpointServiceAccepterConfig_crossAccount(rName string) string { + return acctest.ConfigCompose(acctest.ConfigAlternateAccountProvider(), fmt.Sprintf(` resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" @@ -267,5 +270,5 @@ resource "aws_vpc_endpoint_connection_accepter" "test" { service_id = aws_vpc_endpoint_service.test.id endpoint_id = aws_vpc_endpoint.test.id } -`, rName) +`, rName)) } From 2e7740114d33d7afa56fdfa99549ec30cd21c75a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Dec 2021 11:49:41 -0500 Subject: [PATCH 08/11] r/aws_vpc_endpoint_connection_accepter: 'endpoint_id' -> 'vpc_endpoint_id'. Acceptance test output: % make testacc PKG=ec2 TESTS=TestAccEC2VPCEndpointConnectionAccepter_ ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2VPCEndpointConnectionAccepter_' -timeout 180m === RUN TestAccEC2VPCEndpointConnectionAccepter_crossAccount --- PASS: TestAccEC2VPCEndpointConnectionAccepter_crossAccount (352.10s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 355.650s --- .../ec2/vpc_endpoint_connection_accepter.go | 67 ++++++++++--------- .../vpc_endpoint_connection_accepter_test.go | 18 ++--- ...endpoint_connection_accepter.html.markdown | 6 +- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/internal/service/ec2/vpc_endpoint_connection_accepter.go b/internal/service/ec2/vpc_endpoint_connection_accepter.go index 5c68d52bc1b..0a4b096bbd2 100644 --- a/internal/service/ec2/vpc_endpoint_connection_accepter.go +++ b/internal/service/ec2/vpc_endpoint_connection_accepter.go @@ -21,22 +21,10 @@ func ResourceVPCEndpointConnectionAccepter() *schema.Resource { Delete: resourceVPCEndpointConnectionAccepterDelete, Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - svcID, vpceID := parseVPCEndpointConnectionAccepterID(d.Id()) - - d.Set("service_id", svcID) - d.Set("endpoint_id", vpceID) - - return []*schema.ResourceData{d}, nil - }, + State: schema.ImportStatePassthrough, }, Schema: map[string]*schema.Schema{ - "endpoint_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, "service_id": { Type: schema.TypeString, Required: true, @@ -46,6 +34,11 @@ func ResourceVPCEndpointConnectionAccepter() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "vpc_endpoint_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, }, } } @@ -54,7 +47,7 @@ func resourceVPCEndpointConnectionAccepterCreate(d *schema.ResourceData, meta in conn := meta.(*conns.AWSClient).EC2Conn svcID := d.Get("service_id").(string) - vpceID := d.Get("endpoint_id").(string) + vpceID := d.Get("vpc_endpoint_id").(string) input := &ec2.AcceptVpcEndpointConnectionsInput{ ServiceId: aws.String(svcID), @@ -67,7 +60,7 @@ func resourceVPCEndpointConnectionAccepterCreate(d *schema.ResourceData, meta in return fmt.Errorf("error accepting VPC Endpoint Connection: %s", err.Error()) } - d.SetId(makeVPCEndpointConnectionAccepterID(svcID, vpceID)) + d.SetId(vpcEndpointConnectionAccepterCreateResourceID(svcID, vpceID)) stateConf := &resource.StateChangeConf{ Pending: []string{"pendingAcceptance", "pending"}, @@ -132,14 +125,20 @@ func vpcEndpointConnectionRefresh(conn *ec2.EC2, svcID, vpceID string) resource. func resourceVPCEndpointConnectionAccepterRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - svcID, vpceID := parseVPCEndpointConnectionAccepterID(d.Id()) + serviceID, vpcEndpointID, err := vpcEndpointConnectionAccepterParseResourceID(d.Id()) - vpceConn, state, err := vpcEndpointConnectionRefresh(conn, svcID, vpceID)() + if err != nil { + return err + } + + vpceConn, state, err := vpcEndpointConnectionRefresh(conn, serviceID, vpcEndpointID)() if err != nil && state != "failed" { - return fmt.Errorf("error reading VPC Endpoint Connection from VPC Endpoint Service (%s) to VPC Endpoint (%s): %s", svcID, vpceID, err) + return fmt.Errorf("error reading VPC Endpoint Connection from VPC Endpoint Service (%s) to VPC Endpoint (%s): %s", serviceID, vpcEndpointID, err) } + d.Set("service_id", serviceID) d.Set("state", vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState) + d.Set("vpc_endpoint_id", vpcEndpointID) return nil } @@ -147,31 +146,39 @@ func resourceVPCEndpointConnectionAccepterRead(d *schema.ResourceData, meta inte func resourceVPCEndpointConnectionAccepterDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - svcID, vpceID := parseVPCEndpointConnectionAccepterID(d.Id()) + serviceID, vpcEndpointID, err := vpcEndpointConnectionAccepterParseResourceID(d.Id()) + + if err != nil { + return err + } input := &ec2.RejectVpcEndpointConnectionsInput{ - ServiceId: aws.String(svcID), - VpcEndpointIds: aws.StringSlice([]string{vpceID}), + ServiceId: aws.String(serviceID), + VpcEndpointIds: aws.StringSlice([]string{vpcEndpointID}), } if _, err := conn.RejectVpcEndpointConnections(input); err != nil { - return fmt.Errorf("error rejecting VPC Endpoint Connection from VPC Endpoint (%s) to VPC Endpoint Service (%s): %s", vpceID, svcID, err) + return fmt.Errorf("error rejecting VPC Endpoint Connection from VPC Endpoint (%s) to VPC Endpoint Service (%s): %s", serviceID, vpcEndpointID, err) } return nil } -const vpcEndpointConnectionAccepterIDSeparator = "_" +const vpcEndpointConnectionAccepterResourceIDSeparator = "_" -func makeVPCEndpointConnectionAccepterID(svcID, vpceID string) string { - return strings.Join([]string{svcID, vpceID}, vpcEndpointConnectionAccepterIDSeparator) +func vpcEndpointConnectionAccepterCreateResourceID(serviceID, vpcEndpointID string) string { + parts := []string{serviceID, vpcEndpointID} + id := strings.Join(parts, vpcEndpointConnectionAccepterResourceIDSeparator) + + return id } -func parseVPCEndpointConnectionAccepterID(vpceConnID string) (svcID string, vpceID string) { - split := strings.Split(vpceConnID, vpcEndpointConnectionAccepterIDSeparator) +func vpcEndpointConnectionAccepterParseResourceID(id string) (string, string, error) { + parts := strings.Split(id, vpcEndpointConnectionAccepterResourceIDSeparator) - svcID = split[0] - vpceID = split[1] + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { + return parts[0], parts[1], nil + } - return + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected ServiceID%[2]sVPCEndpointID", id, vpcEndpointConnectionAccepterResourceIDSeparator) } diff --git a/internal/service/ec2/vpc_endpoint_connection_accepter_test.go b/internal/service/ec2/vpc_endpoint_connection_accepter_test.go index d4eb40ee73c..8de12cf710b 100644 --- a/internal/service/ec2/vpc_endpoint_connection_accepter_test.go +++ b/internal/service/ec2/vpc_endpoint_connection_accepter_test.go @@ -15,7 +15,7 @@ import ( tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" ) -func TestAccVpcEndpointServiceAccepter_crossAccount(t *testing.T) { +func TestAccEC2VPCEndpointConnectionAccepter_crossAccount(t *testing.T) { var providers []*schema.Provider resourceName := "aws_vpc_endpoint_connection_accepter.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -27,16 +27,16 @@ func TestAccVpcEndpointServiceAccepter_crossAccount(t *testing.T) { }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), ProviderFactories: acctest.FactoriesAlternate(&providers), - CheckDestroy: testAccVPCEndpointServiceAccepterDestroy, + CheckDestroy: testAccCheckVpcEndpointConnectionAccepterDestroy, Steps: []resource.TestStep{ { - Config: testAccVPCEndpointServiceAccepterConfig_crossAccount(rName), + Config: testAccVPCEndpointConnectionAccepterConfig_crossAccount(rName), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "state", "available"), ), }, { - Config: testAccVPCEndpointServiceAccepterConfig_crossAccount(rName), + Config: testAccVPCEndpointConnectionAccepterConfig_crossAccount(rName), ResourceName: resourceName, ImportState: true, ImportStateVerify: true, @@ -45,7 +45,7 @@ func TestAccVpcEndpointServiceAccepter_crossAccount(t *testing.T) { }) } -func testAccVPCEndpointServiceAccepterDestroy(s *terraform.State) error { +func testAccCheckVpcEndpointConnectionAccepterDestroy(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn for _, rs := range s.RootModule().Resources { @@ -54,7 +54,7 @@ func testAccVPCEndpointServiceAccepterDestroy(s *terraform.State) error { } svcID := rs.Primary.Attributes["service_id"] - vpceID := rs.Primary.Attributes["endpoint_id"] + vpceID := rs.Primary.Attributes["vpc_endpoint_id"] input := &ec2.DescribeVpcEndpointConnectionsInput{ Filters: tfec2.BuildAttributeFilterList(map[string]string{"service-id": svcID}), @@ -84,7 +84,7 @@ func testAccVPCEndpointServiceAccepterDestroy(s *terraform.State) error { return nil } -func testAccVPCEndpointServiceAccepterConfig_crossAccount(rName string) string { +func testAccVPCEndpointConnectionAccepterConfig_crossAccount(rName string) string { return acctest.ConfigCompose(acctest.ConfigAlternateAccountProvider(), fmt.Sprintf(` resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" @@ -267,8 +267,8 @@ resource "aws_vpc_endpoint" "test" { } resource "aws_vpc_endpoint_connection_accepter" "test" { - service_id = aws_vpc_endpoint_service.test.id - endpoint_id = aws_vpc_endpoint.test.id + service_id = aws_vpc_endpoint_service.test.id + vpc_endpoint_id = aws_vpc_endpoint.test.id } `, rName)) } diff --git a/website/docs/r/vpc_endpoint_connection_accepter.html.markdown b/website/docs/r/vpc_endpoint_connection_accepter.html.markdown index eb9e55adfdf..2743fde0a48 100644 --- a/website/docs/r/vpc_endpoint_connection_accepter.html.markdown +++ b/website/docs/r/vpc_endpoint_connection_accepter.html.markdown @@ -34,8 +34,8 @@ resource "aws_vpc_endpoint" "example" { } resource "aws_vpc_endpoint_connection_accepter" "example" { - service_id = aws_vpc_endpoint_service.example.id - endpoint_id = aws_vpc_endpoint.example.id + service_id = aws_vpc_endpoint_service.example.id + vpc_endpoint_id = aws_vpc_endpoint.example.id } ``` @@ -44,7 +44,7 @@ resource "aws_vpc_endpoint_connection_accepter" "example" { The following arguments are supported: * `service_id` - (Required) AWS VPC Endpoint Service ID. -* `endpoint_id` - (Required) AWS VPC Endpoint ID. +* `vpc_endpoint_id` - (Required) AWS VPC Endpoint ID. ## Attributes Reference From 372f5b22797250fc37265a514716312d5a5994da Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Dec 2021 13:00:10 -0500 Subject: [PATCH 09/11] r/aws_vpc_endpoint_connection_accepter: 'service_id' -> 'vpc_endpoint_service_id'. Acceptance test output: % make testacc PKG=ec2 TESTS=TestAccEC2VPCEndpointConnectionAccepter_ ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2VPCEndpointConnectionAccepter_' -timeout 180m === RUN TestAccEC2VPCEndpointConnectionAccepter_crossAccount --- PASS: TestAccEC2VPCEndpointConnectionAccepter_crossAccount (399.50s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 405.824s --- .../ec2/vpc_endpoint_connection_accepter.go | 34 +++++++++---------- .../vpc_endpoint_connection_accepter_test.go | 6 ++-- ...endpoint_connection_accepter.html.markdown | 6 ++-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/internal/service/ec2/vpc_endpoint_connection_accepter.go b/internal/service/ec2/vpc_endpoint_connection_accepter.go index 0a4b096bbd2..d1a94b93073 100644 --- a/internal/service/ec2/vpc_endpoint_connection_accepter.go +++ b/internal/service/ec2/vpc_endpoint_connection_accepter.go @@ -25,11 +25,6 @@ func ResourceVPCEndpointConnectionAccepter() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "service_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, "state": { Type: schema.TypeString, Computed: true, @@ -39,6 +34,11 @@ func ResourceVPCEndpointConnectionAccepter() *schema.Resource { Required: true, ForceNew: true, }, + "vpc_endpoint_service_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, }, } } @@ -46,26 +46,26 @@ func ResourceVPCEndpointConnectionAccepter() *schema.Resource { func resourceVPCEndpointConnectionAccepterCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - svcID := d.Get("service_id").(string) - vpceID := d.Get("vpc_endpoint_id").(string) - + serviceID := d.Get("vpc_endpoint_service_id").(string) + vpcEndpointID := d.Get("vpc_endpoint_id").(string) input := &ec2.AcceptVpcEndpointConnectionsInput{ - ServiceId: aws.String(svcID), - VpcEndpointIds: aws.StringSlice([]string{vpceID}), + ServiceId: aws.String(serviceID), + VpcEndpointIds: aws.StringSlice([]string{vpcEndpointID}), } - log.Printf("[DEBUG] Accepting VPC Endpoint Connection: %#v", input) + log.Printf("[DEBUG] Accepting VPC Endpoint Connection: %s", input) _, err := conn.AcceptVpcEndpointConnections(input) + if err != nil { - return fmt.Errorf("error accepting VPC Endpoint Connection: %s", err.Error()) + return fmt.Errorf("error accepting VPC Endpoint Connection: %w", err) } - d.SetId(vpcEndpointConnectionAccepterCreateResourceID(svcID, vpceID)) + d.SetId(vpcEndpointConnectionAccepterCreateResourceID(serviceID, vpcEndpointID)) stateConf := &resource.StateChangeConf{ Pending: []string{"pendingAcceptance", "pending"}, Target: []string{"available"}, - Refresh: vpcEndpointConnectionRefresh(conn, svcID, vpceID), + Refresh: vpcEndpointConnectionRefresh(conn, serviceID, vpcEndpointID), Timeout: d.Timeout(schema.TimeoutCreate), Delay: 5 * time.Second, MinTimeout: 5 * time.Second, @@ -73,7 +73,7 @@ func resourceVPCEndpointConnectionAccepterCreate(d *schema.ResourceData, meta in vpceConn, err := stateConf.WaitForStateContext(context.Background()) if err != nil { - return fmt.Errorf("error waiting for VPC Endpoint (%s) to be accepted by VPC Endpoint Service (%s): %s", vpceID, svcID, err) + return fmt.Errorf("error waiting for VPC Endpoint (%s) to be accepted by VPC Endpoint Service (%s): %s", vpcEndpointID, serviceID, err) } d.Set("state", vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState) @@ -136,9 +136,9 @@ func resourceVPCEndpointConnectionAccepterRead(d *schema.ResourceData, meta inte return fmt.Errorf("error reading VPC Endpoint Connection from VPC Endpoint Service (%s) to VPC Endpoint (%s): %s", serviceID, vpcEndpointID, err) } - d.Set("service_id", serviceID) d.Set("state", vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState) d.Set("vpc_endpoint_id", vpcEndpointID) + d.Set("vpc_endpoint_service_id", serviceID) return nil } @@ -180,5 +180,5 @@ func vpcEndpointConnectionAccepterParseResourceID(id string) (string, string, er return parts[0], parts[1], nil } - return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected ServiceID%[2]sVPCEndpointID", id, vpcEndpointConnectionAccepterResourceIDSeparator) + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected VPCEndpointServiceID%[2]sVPCEndpointID", id, vpcEndpointConnectionAccepterResourceIDSeparator) } diff --git a/internal/service/ec2/vpc_endpoint_connection_accepter_test.go b/internal/service/ec2/vpc_endpoint_connection_accepter_test.go index 8de12cf710b..4052282191a 100644 --- a/internal/service/ec2/vpc_endpoint_connection_accepter_test.go +++ b/internal/service/ec2/vpc_endpoint_connection_accepter_test.go @@ -53,7 +53,7 @@ func testAccCheckVpcEndpointConnectionAccepterDestroy(s *terraform.State) error continue } - svcID := rs.Primary.Attributes["service_id"] + svcID := rs.Primary.Attributes["vpc_endpoint_service_id"] vpceID := rs.Primary.Attributes["vpc_endpoint_id"] input := &ec2.DescribeVpcEndpointConnectionsInput{ @@ -267,8 +267,8 @@ resource "aws_vpc_endpoint" "test" { } resource "aws_vpc_endpoint_connection_accepter" "test" { - service_id = aws_vpc_endpoint_service.test.id - vpc_endpoint_id = aws_vpc_endpoint.test.id + vpc_endpoint_service_id = aws_vpc_endpoint_service.test.id + vpc_endpoint_id = aws_vpc_endpoint.test.id } `, rName)) } diff --git a/website/docs/r/vpc_endpoint_connection_accepter.html.markdown b/website/docs/r/vpc_endpoint_connection_accepter.html.markdown index 2743fde0a48..d6ebbdcf6ab 100644 --- a/website/docs/r/vpc_endpoint_connection_accepter.html.markdown +++ b/website/docs/r/vpc_endpoint_connection_accepter.html.markdown @@ -34,8 +34,8 @@ resource "aws_vpc_endpoint" "example" { } resource "aws_vpc_endpoint_connection_accepter" "example" { - service_id = aws_vpc_endpoint_service.example.id - vpc_endpoint_id = aws_vpc_endpoint.example.id + vpc_endpoint_service_id = aws_vpc_endpoint_service.example.id + vpc_endpoint_id = aws_vpc_endpoint.example.id } ``` @@ -43,8 +43,8 @@ resource "aws_vpc_endpoint_connection_accepter" "example" { The following arguments are supported: -* `service_id` - (Required) AWS VPC Endpoint Service ID. * `vpc_endpoint_id` - (Required) AWS VPC Endpoint ID. +* `vpc_endpoint_service_id` - (Required) AWS VPC Endpoint Service ID. ## Attributes Reference From beb42be23fe65e9f5b88f04eeff70ae0a73b6fb2 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Dec 2021 15:31:18 -0500 Subject: [PATCH 10/11] Add and use 'FindVPCEndpointConnectionByServiceIDAndVPCEndpointID'. --- internal/service/ec2/find.go | 45 ++++++++ internal/service/ec2/status.go | 16 +++ .../ec2/vpc_endpoint_connection_accepter.go | 102 ++++++------------ .../vpc_endpoint_connection_accepter_test.go | 29 ++--- internal/service/ec2/wait.go | 19 ++++ ...endpoint_connection_accepter.html.markdown | 2 +- 6 files changed, 123 insertions(+), 90 deletions(-) diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 63c525a41c4..c67a345301d 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -1349,3 +1349,48 @@ func FindPlacementGroupByName(conn *ec2.EC2, name string) (*ec2.PlacementGroup, return placementGroup, nil } + +func FindVPCEndpointConnectionByServiceIDAndVPCEndpointID(conn *ec2.EC2, serviceID, vpcEndpointID string) (*ec2.VpcEndpointConnection, error) { + input := &ec2.DescribeVpcEndpointConnectionsInput{ + Filters: BuildAttributeFilterList(map[string]string{ + "service-id": serviceID, + // "InvalidFilter: The filter vpc-endpoint-id is invalid" + // "vpc-endpoint-id ": vpcEndpointID, + }), + } + + var output *ec2.VpcEndpointConnection + + err := conn.DescribeVpcEndpointConnectionsPages(input, func(page *ec2.DescribeVpcEndpointConnectionsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.VpcEndpointConnections { + if aws.StringValue(v.VpcEndpointId) == vpcEndpointID { + output = v + + return false + } + } + + return !lastPage + }) + + if err != nil { + return nil, err + } + + if output == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if vpcEndpointState := aws.StringValue(output.VpcEndpointState); vpcEndpointState == VPCEndpointStateDeleted { + return nil, &resource.NotFoundError{ + Message: vpcEndpointState, + LastRequest: input, + } + } + + return output, nil +} diff --git a/internal/service/ec2/status.go b/internal/service/ec2/status.go index a4a6af3d1bf..1949eec6a70 100644 --- a/internal/service/ec2/status.go +++ b/internal/service/ec2/status.go @@ -641,3 +641,19 @@ func StatusEBSSnapshotImport(conn *ec2.EC2, importTaskId string) resource.StateR } } } + +func statusVPCEndpointConnectionVPCEndpointState(conn *ec2.EC2, serviceID, vpcEndpointID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindVPCEndpointConnectionByServiceIDAndVPCEndpointID(conn, serviceID, vpcEndpointID) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, aws.StringValue(output.VpcEndpointState), nil + } +} diff --git a/internal/service/ec2/vpc_endpoint_connection_accepter.go b/internal/service/ec2/vpc_endpoint_connection_accepter.go index d1a94b93073..463c32283f2 100644 --- a/internal/service/ec2/vpc_endpoint_connection_accepter.go +++ b/internal/service/ec2/vpc_endpoint_connection_accepter.go @@ -1,17 +1,16 @@ package ec2 import ( - "context" "fmt" "log" "strings" - "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func ResourceVPCEndpointConnectionAccepter() *schema.Resource { @@ -48,6 +47,7 @@ func resourceVPCEndpointConnectionAccepterCreate(d *schema.ResourceData, meta in serviceID := d.Get("vpc_endpoint_service_id").(string) vpcEndpointID := d.Get("vpc_endpoint_id").(string) + id := VPCEndpointConnectionAccepterCreateResourceID(serviceID, vpcEndpointID) input := &ec2.AcceptVpcEndpointConnectionsInput{ ServiceId: aws.String(serviceID), VpcEndpointIds: aws.StringSlice([]string{vpcEndpointID}), @@ -57,88 +57,44 @@ func resourceVPCEndpointConnectionAccepterCreate(d *schema.ResourceData, meta in _, err := conn.AcceptVpcEndpointConnections(input) if err != nil { - return fmt.Errorf("error accepting VPC Endpoint Connection: %w", err) + return fmt.Errorf("error accepting VPC Endpoint Connection (%s): %w", id, err) } - d.SetId(vpcEndpointConnectionAccepterCreateResourceID(serviceID, vpcEndpointID)) + d.SetId(id) - stateConf := &resource.StateChangeConf{ - Pending: []string{"pendingAcceptance", "pending"}, - Target: []string{"available"}, - Refresh: vpcEndpointConnectionRefresh(conn, serviceID, vpcEndpointID), - Timeout: d.Timeout(schema.TimeoutCreate), - Delay: 5 * time.Second, - MinTimeout: 5 * time.Second, - } + _, err = waitVPCEndpointConnectionAccepted(conn, serviceID, vpcEndpointID, d.Timeout(schema.TimeoutCreate)) - vpceConn, err := stateConf.WaitForStateContext(context.Background()) if err != nil { - return fmt.Errorf("error waiting for VPC Endpoint (%s) to be accepted by VPC Endpoint Service (%s): %s", vpcEndpointID, serviceID, err) + return fmt.Errorf("error waiting for VPC Endpoint Connection (%s) to be accepted: %w", d.Id(), err) } - d.Set("state", vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState) - return resourceVPCEndpointConnectionAccepterRead(d, meta) } -func vpcEndpointConnectionRefresh(conn *ec2.EC2, svcID, vpceID string) resource.StateRefreshFunc { - return func() (interface{}, string, error) { - log.Printf("[DEBUG] Reading VPC Endpoint Connections for VPC Endpoint Service (%s)", svcID) - - input := &ec2.DescribeVpcEndpointConnectionsInput{ - Filters: BuildAttributeFilterList(map[string]string{"service-id": svcID}), - } - - var vpceConn *ec2.VpcEndpointConnection - - paginator := func(page *ec2.DescribeVpcEndpointConnectionsOutput, lastPage bool) bool { - for _, c := range page.VpcEndpointConnections { - if aws.StringValue(c.VpcEndpointId) == vpceID { - log.Printf("[DEBUG] Found VPC Endpoint Connection from VPC Endpoint Service (%s) to VPC Endpoint (%s): %s", svcID, vpceID, *c) - vpceConn = c - return false - } - } - return !lastPage - } - - if err := conn.DescribeVpcEndpointConnectionsPages(input, paginator); err != nil { - return nil, "", err - } - - if vpceConn == nil { - return nil, "", fmt.Errorf("VPC Endpoint Connection from VPC Endpoint Service (%s) to VPC Endpoint (%s) not found", svcID, vpceID) - } - - state := aws.StringValue(vpceConn.VpcEndpointState) - log.Printf("[DEBUG] state %s", state) - - // No point in retrying if the endpoint is in a failed state. - if state == "failed" { - return nil, state, fmt.Errorf("VPC Endpoint Connection state %q", state) - } - - return *vpceConn, state, nil - } -} - func resourceVPCEndpointConnectionAccepterRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - serviceID, vpcEndpointID, err := vpcEndpointConnectionAccepterParseResourceID(d.Id()) + serviceID, vpcEndpointID, err := VPCEndpointConnectionAccepterParseResourceID(d.Id()) if err != nil { return err } - vpceConn, state, err := vpcEndpointConnectionRefresh(conn, serviceID, vpcEndpointID)() - if err != nil && state != "failed" { - return fmt.Errorf("error reading VPC Endpoint Connection from VPC Endpoint Service (%s) to VPC Endpoint (%s): %s", serviceID, vpcEndpointID, err) + vpcEndpointConnection, err := FindVPCEndpointConnectionByServiceIDAndVPCEndpointID(conn, serviceID, vpcEndpointID) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] VPC Endpoint Connection %s not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error reading VPC Endpoint Connection (%s): %w", d.Id(), err) } - d.Set("state", vpceConn.(ec2.VpcEndpointConnection).VpcEndpointState) - d.Set("vpc_endpoint_id", vpcEndpointID) - d.Set("vpc_endpoint_service_id", serviceID) + d.Set("vpc_endpoint_id", vpcEndpointConnection.VpcEndpointId) + d.Set("vpc_endpoint_service_id", vpcEndpointConnection.ServiceId) + d.Set("vpc_endpoint_state", vpcEndpointConnection.VpcEndpointState) return nil } @@ -146,7 +102,7 @@ func resourceVPCEndpointConnectionAccepterRead(d *schema.ResourceData, meta inte func resourceVPCEndpointConnectionAccepterDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - serviceID, vpcEndpointID, err := vpcEndpointConnectionAccepterParseResourceID(d.Id()) + serviceID, vpcEndpointID, err := VPCEndpointConnectionAccepterParseResourceID(d.Id()) if err != nil { return err @@ -157,8 +113,14 @@ func resourceVPCEndpointConnectionAccepterDelete(d *schema.ResourceData, meta in VpcEndpointIds: aws.StringSlice([]string{vpcEndpointID}), } - if _, err := conn.RejectVpcEndpointConnections(input); err != nil { - return fmt.Errorf("error rejecting VPC Endpoint Connection from VPC Endpoint (%s) to VPC Endpoint Service (%s): %s", serviceID, vpcEndpointID, err) + _, err = conn.RejectVpcEndpointConnections(input) + + if tfawserr.ErrCodeEquals(err, ErrCodeInvalidVPCEndpointServiceIdNotFound) { + return nil + } + + if err != nil { + return fmt.Errorf("error rejecting VPC Endpoint Connection (%s): %w", d.Id(), err) } return nil @@ -166,14 +128,14 @@ func resourceVPCEndpointConnectionAccepterDelete(d *schema.ResourceData, meta in const vpcEndpointConnectionAccepterResourceIDSeparator = "_" -func vpcEndpointConnectionAccepterCreateResourceID(serviceID, vpcEndpointID string) string { +func VPCEndpointConnectionAccepterCreateResourceID(serviceID, vpcEndpointID string) string { parts := []string{serviceID, vpcEndpointID} id := strings.Join(parts, vpcEndpointConnectionAccepterResourceIDSeparator) return id } -func vpcEndpointConnectionAccepterParseResourceID(id string) (string, string, error) { +func VPCEndpointConnectionAccepterParseResourceID(id string) (string, string, error) { parts := strings.Split(id, vpcEndpointConnectionAccepterResourceIDSeparator) if len(parts) == 2 && parts[0] != "" && parts[1] != "" { diff --git a/internal/service/ec2/vpc_endpoint_connection_accepter_test.go b/internal/service/ec2/vpc_endpoint_connection_accepter_test.go index 4052282191a..1386cf178a8 100644 --- a/internal/service/ec2/vpc_endpoint_connection_accepter_test.go +++ b/internal/service/ec2/vpc_endpoint_connection_accepter_test.go @@ -4,7 +4,6 @@ import ( "fmt" "testing" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -13,6 +12,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func TestAccEC2VPCEndpointConnectionAccepter_crossAccount(t *testing.T) { @@ -32,7 +32,7 @@ func TestAccEC2VPCEndpointConnectionAccepter_crossAccount(t *testing.T) { { Config: testAccVPCEndpointConnectionAccepterConfig_crossAccount(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "state", "available"), + resource.TestCheckResourceAttr(resourceName, "vpc_endpoint_state", "available"), ), }, { @@ -53,32 +53,23 @@ func testAccCheckVpcEndpointConnectionAccepterDestroy(s *terraform.State) error continue } - svcID := rs.Primary.Attributes["vpc_endpoint_service_id"] - vpceID := rs.Primary.Attributes["vpc_endpoint_id"] + serviceID, vpcEndpointID, err := tfec2.VPCEndpointConnectionAccepterParseResourceID(rs.Primary.ID) - input := &ec2.DescribeVpcEndpointConnectionsInput{ - Filters: tfec2.BuildAttributeFilterList(map[string]string{"service-id": svcID}), + if err != nil { + return err } - var foundAvailable bool + _, err = tfec2.FindVPCEndpointConnectionByServiceIDAndVPCEndpointID(conn, serviceID, vpcEndpointID) - paginator := func(page *ec2.DescribeVpcEndpointConnectionsOutput, lastPage bool) bool { - for _, c := range page.VpcEndpointConnections { - if aws.StringValue(c.VpcEndpointId) == vpceID && aws.StringValue(c.VpcEndpointState) == "available" { - foundAvailable = true - return false - } - } - return !lastPage + if tfresource.NotFound(err) { + continue } - if err := conn.DescribeVpcEndpointConnectionsPages(input, paginator); err != nil { + if err != nil { return err } - if foundAvailable { - return fmt.Errorf("AWS VPC Endpoint Service (%s) still has connection from AWS VPC Endpoint (%s) in available status", svcID, vpceID) - } + return fmt.Errorf("VPC Endpoint Connection %s still exists", rs.Primary.ID) } return nil diff --git a/internal/service/ec2/wait.go b/internal/service/ec2/wait.go index c9838b8784b..dc5248ace8d 100644 --- a/internal/service/ec2/wait.go +++ b/internal/service/ec2/wait.go @@ -1031,3 +1031,22 @@ func WaitEBSSnapshotImportComplete(conn *ec2.EC2, importTaskID string) (*ec2.Sna return detail.(*ec2.SnapshotTaskDetail), nil } } + +func waitVPCEndpointConnectionAccepted(conn *ec2.EC2, serviceID, vpcEndpointID string, timeout time.Duration) (*ec2.VpcEndpointConnection, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{VPCEndpointStatePendingAcceptance, VPCEndpointStatePending}, + Target: []string{VPCEndpointStateAvailable}, + Refresh: statusVPCEndpointConnectionVPCEndpointState(conn, serviceID, vpcEndpointID), + Timeout: timeout, + Delay: 5 * time.Second, + MinTimeout: 5 * time.Second, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*ec2.VpcEndpointConnection); ok { + return output, err + } + + return nil, err +} diff --git a/website/docs/r/vpc_endpoint_connection_accepter.html.markdown b/website/docs/r/vpc_endpoint_connection_accepter.html.markdown index d6ebbdcf6ab..73a66cae95b 100644 --- a/website/docs/r/vpc_endpoint_connection_accepter.html.markdown +++ b/website/docs/r/vpc_endpoint_connection_accepter.html.markdown @@ -51,7 +51,7 @@ The following arguments are supported: In addition to all arguments above, the following attributes are exported: * `id` - The ID of the VPC Endpoint Connection. -* `state` - State of the VPC Endpoint Connection. +* `vpc_endpoint_state` - State of the VPC Endpoint. ## Import From 99a7fe64c0deff021a0f3acc3fd34eb64380de43 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Dec 2021 15:40:20 -0500 Subject: [PATCH 11/11] r/aws_vpc_endpoint_connection_accepter: 'state' -> 'vpc_endpoint_state'. --- internal/service/ec2/vpc_endpoint_connection_accepter.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/service/ec2/vpc_endpoint_connection_accepter.go b/internal/service/ec2/vpc_endpoint_connection_accepter.go index 463c32283f2..de758efcd92 100644 --- a/internal/service/ec2/vpc_endpoint_connection_accepter.go +++ b/internal/service/ec2/vpc_endpoint_connection_accepter.go @@ -24,10 +24,6 @@ func ResourceVPCEndpointConnectionAccepter() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "state": { - Type: schema.TypeString, - Computed: true, - }, "vpc_endpoint_id": { Type: schema.TypeString, Required: true, @@ -38,6 +34,10 @@ func ResourceVPCEndpointConnectionAccepter() *schema.Resource { Required: true, ForceNew: true, }, + "vpc_endpoint_state": { + Type: schema.TypeString, + Computed: true, + }, }, } }