From 574baf78cb5e60facc502190867d5d48805f883e Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Mon, 19 Jun 2023 20:44:55 +0200 Subject: [PATCH 1/7] [WIP] - create instance connect endpoint --- .../ec2/ec2_instance_connect_endpoint.go | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 internal/service/ec2/ec2_instance_connect_endpoint.go diff --git a/internal/service/ec2/ec2_instance_connect_endpoint.go b/internal/service/ec2/ec2_instance_connect_endpoint.go new file mode 100644 index 000000000000..d6d5248fdc68 --- /dev/null +++ b/internal/service/ec2/ec2_instance_connect_endpoint.go @@ -0,0 +1,114 @@ +package ec2 + +import ( + "context" + "log" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @SDKResource("aws_ec2_instance_state") +func ResourceInstanceConnectEndpoint() *schema.Resource { + return &schema.Resource{ + CreateWithoutTimeout: resourceInstanceConnectEndpointCreate, + ReadWithoutTimeout: resourceInstanceConnectEndpointRead, + UpdateWithoutTimeout: resourceInstanceConnectEndpointUpdate, + DeleteWithoutTimeout: resourceInstanceConnectEndpointDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Update: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(1 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "subnet_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "security_group_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "preserve_client_ip": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Default: true, + }, + }, + } +} + +func resourceInstanceConnectEndpointCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).EC2Conn(ctx) + instanceId := d.Get("instance_id").(string) + + d.SetId(d.Get("instance_id").(string)) + + return resourceInstanceConnectEndpointRead(ctx, d, meta) +} + +func resourceInstanceConnectEndpointRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).EC2Conn(ctx) + + state, err := FindInstanceConnectEndpointByID(ctx, conn, d.Id()) + + if !d.IsNewResource() && tfresource.NotFound(err) { + create.LogNotFoundRemoveState(names.EC2, create.ErrActionReading, ResInstanceConnectEndpoint, d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return create.DiagError(names.EC2, create.ErrActionReading, ResInstanceConnectEndpoint, d.Id(), err) + } + + d.Set("instance_id", d.Id()) + d.Set("state", state.Name) + d.Set("force", d.Get("force").(bool)) + + return nil +} + +func resourceInstanceConnectEndpointUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).EC2Conn(ctx) + + instance, instanceErr := WaitInstanceReadyWithContext(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + + if instanceErr != nil { + return create.DiagError(names.EC2, create.ErrActionReading, ResInstance, aws.StringValue(instance.InstanceId), instanceErr) + } + + if d.HasChange("state") { + o, n := d.GetChange("state") + err := UpdateInstanceConnectEndpoint(ctx, conn, d.Id(), o.(string), n.(string), d.Get("force").(bool)) + + if err != nil { + return err + } + } + + return resourceInstanceConnectEndpointRead(ctx, d, meta) +} + +func resourceInstanceConnectEndpointDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + log.Printf("[DEBUG] %s %s deleting an aws_ec2_instance_state resource only stops managing instance state, The Instance is left in its current state.: %s", names.EC2, ResInstanceConnectEndpoint, d.Id()) + + return nil +} From e9fd1395e456f9a2402abc1940c9a2bef56f51ba Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Mon, 19 Jun 2023 20:44:55 +0200 Subject: [PATCH 2/7] [WIP] - create instance connect endpoint --- .../ec2/ec2_instance_connect_endpoint.go | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 internal/service/ec2/ec2_instance_connect_endpoint.go diff --git a/internal/service/ec2/ec2_instance_connect_endpoint.go b/internal/service/ec2/ec2_instance_connect_endpoint.go new file mode 100644 index 000000000000..e596e9436f79 --- /dev/null +++ b/internal/service/ec2/ec2_instance_connect_endpoint.go @@ -0,0 +1,134 @@ +package ec2 + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +// @SDKResource("aws_ec2_instance_connect_endpoint") +func ResourceInstanceConnectEndpoint() *schema.Resource { + return &schema.Resource{ + CreateWithoutTimeout: resourceInstanceConnectEndpointCreate, + ReadWithoutTimeout: resourceInstanceConnectEndpointRead, + UpdateWithoutTimeout: resourceInstanceConnectEndpointUpdate, + DeleteWithoutTimeout: resourceInstanceConnectEndpointDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Update: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(1 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "subnet_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "security_group_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "preserve_client_ip": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Default: true, + }, + }, + } +} + +func resourceInstanceConnectEndpointCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).EC2Conn(ctx) + + input := &ec2.CreateInstanceConnectEndpointInput{} + + output, err := conn.CreateInstanceConnectEndpointWithContext(ctx, input) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "importing EC2 Key Pair (%s): %s", keyName, err) + } + + d.SetId(aws.StringValue(output.KeyName)) + + return append(diags, resourceInstanceConnectEndpointRead(ctx, d, meta)...) +} + +func resourceInstanceConnectEndpointRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).EC2Conn(ctx) + + InstanceConnectEndpoint, err := FindInstanceConnectEndpointByName(ctx, conn, d.Id()) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] EC2 Key Pair (%s) not found, removing from state", d.Id()) + d.SetId("") + return diags + } + + if err != nil { + return sdkdiag.AppendErrorf(diags, "reading EC2 Key Pair (%s): %s", d.Id(), err) + } + + arn := arn.ARN{ + Partition: meta.(*conns.AWSClient).Partition, + Service: ec2.ServiceName, + Region: meta.(*conns.AWSClient).Region, + AccountID: meta.(*conns.AWSClient).AccountID, + Resource: fmt.Sprintf("key-pair/%s", d.Id()), + }.String() + + d.Set("arn", arn) + d.Set("fingerprint", InstanceConnectEndpoint.KeyFingerprint) + d.Set("key_name", InstanceConnectEndpoint.KeyName) + d.Set("key_name_prefix", create.NamePrefixFromName(aws.StringValue(InstanceConnectEndpoint.KeyName))) + d.Set("key_type", InstanceConnectEndpoint.KeyType) + d.Set("key_pair_id", InstanceConnectEndpoint.InstanceConnectEndpointId) + + setTagsOut(ctx, InstanceConnectEndpoint.Tags) + + return diags +} + +func resourceInstanceConnectEndpointUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + + // Tags only. + + return append(diags, resourceInstanceConnectEndpointRead(ctx, d, meta)...) +} + +func resourceInstanceConnectEndpointDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).EC2Conn(ctx) + + log.Printf("[DEBUG] Deleting EC2 Key Pair: %s", d.Id()) + _, err := conn.DeleteInstanceConnectEndpointWithContext(ctx, &ec2.DeleteInstanceConnectEndpointInput{ + KeyName: aws.String(d.Id()), + }) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "deleting EC2 Key Pair (%s): %s", d.Id(), err) + } + + return diags +} From 5e184ce0dc61aca61775510a02505b1dee6b0e12 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Mon, 19 Jun 2023 21:23:00 +0200 Subject: [PATCH 3/7] add `aws_ec2_instance_connect_endpoint` to service package gen --- internal/service/ec2/service_package_gen.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/service/ec2/service_package_gen.go b/internal/service/ec2/service_package_gen.go index b2032b188db9..8e2100d98ec4 100644 --- a/internal/service/ec2/service_package_gen.go +++ b/internal/service/ec2/service_package_gen.go @@ -557,6 +557,13 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka IdentifierAttribute: "id", }, }, + { + Factory: ResourceInstanceConnectEndpoint, + TypeName: "aws_ec2_instance_connect_endpoint", + Tags: &types.ServicePackageResourceTags{ + IdentifierAttribute: "id", + }, + }, { Factory: ResourceInstanceState, TypeName: "aws_ec2_instance_state", From 1b9b1e15d7a3f09cf860522b6176986cece94abb Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Mon, 19 Jun 2023 21:23:04 +0200 Subject: [PATCH 4/7] Update consts.go --- internal/service/ec2/consts.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/service/ec2/consts.go b/internal/service/ec2/consts.go index ab979ce5f971..0c136668b132 100644 --- a/internal/service/ec2/consts.go +++ b/internal/service/ec2/consts.go @@ -290,6 +290,11 @@ const ( ResInstanceState = "Instance State" ) +const ( + ResInstanceConnectEndpoint = "Instance Connect Endpoint" + ResInstanceConnectEndpointState = "Instance Connect Endpoint State" +) + const ( gatewayIDLocal = "local" gatewayIDVPCLattice = "VpcLattice" From 4dd9cb793dbee75ec4a1a6f7e52987cdb6925e10 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Mon, 19 Jun 2023 21:23:06 +0200 Subject: [PATCH 5/7] Update ec2_instance_connect_endpoint.go --- .../ec2/ec2_instance_connect_endpoint.go | 120 ++++++++++++++---- 1 file changed, 93 insertions(+), 27 deletions(-) diff --git a/internal/service/ec2/ec2_instance_connect_endpoint.go b/internal/service/ec2/ec2_instance_connect_endpoint.go index e596e9436f79..b45bad497f0b 100644 --- a/internal/service/ec2/ec2_instance_connect_endpoint.go +++ b/internal/service/ec2/ec2_instance_connect_endpoint.go @@ -2,22 +2,25 @@ package ec2 import ( "context" - "fmt" "log" "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" + "github.com/hashicorp/terraform-provider-aws/internal/flex" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" + "github.com/hashicorp/terraform-provider-aws/names" ) // @SDKResource("aws_ec2_instance_connect_endpoint") +// @Tags(identifierAttribute="id") func ResourceInstanceConnectEndpoint() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceInstanceConnectEndpointCreate, @@ -36,23 +39,67 @@ func ResourceInstanceConnectEndpoint() *schema.Resource { }, Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "availability_zone": { + Type: schema.TypeString, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "dns_name": { + Type: schema.TypeString, + Computed: true, + }, + "fips_dns_name": { + Type: schema.TypeString, + Computed: true, + }, "subnet_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, + "network_interface_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "owner_id": { + Type: schema.TypeString, + Computed: true, + }, "security_group_ids": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "state": { + Type: schema.TypeString, + Computed: true, + }, "preserve_client_ip": { Type: schema.TypeBool, Optional: true, Computed: true, Default: true, }, + "vpc_id": { + Type: schema.TypeString, + Computed: true, + }, + names.AttrTags: tftags.TagsSchema(), + names.AttrTagsAll: tftags.TagsSchemaComputed(), }, + CustomizeDiff: verify.SetTagsDiff, } } @@ -60,15 +107,26 @@ func resourceInstanceConnectEndpointCreate(ctx context.Context, d *schema.Resour var diags diag.Diagnostics conn := meta.(*conns.AWSClient).EC2Conn(ctx) - input := &ec2.CreateInstanceConnectEndpointInput{} + input := &ec2.CreateInstanceConnectEndpointInput{ + SubnetId: aws.String(d.Get("subnet_id").(string)), + TagSpecifications: getTagSpecificationsIn(ctx, ec2.ResourceTypeInstanceConnectEndpoint), + } + + if attr, ok := d.GetOk("autoscaling_groups"); ok { + input.SecurityGroupIds = flex.ExpandStringSet(attr.(*schema.Set)) + } + + if v, ok := d.GetOk("disable_rollback"); ok { + input.PreserveClientIp = aws.Bool(v.(bool)) + } output, err := conn.CreateInstanceConnectEndpointWithContext(ctx, input) if err != nil { - return sdkdiag.AppendErrorf(diags, "importing EC2 Key Pair (%s): %s", keyName, err) + return sdkdiag.AppendErrorf(diags, "creating EC2 Instance Connect Endpoint: %s", err) } - d.SetId(aws.StringValue(output.KeyName)) + d.SetId(aws.StringValue(output.InstanceConnectEndpoint.InstanceConnectEndpointId)) return append(diags, resourceInstanceConnectEndpointRead(ctx, d, meta)...) } @@ -77,34 +135,43 @@ func resourceInstanceConnectEndpointRead(ctx context.Context, d *schema.Resource var diags diag.Diagnostics conn := meta.(*conns.AWSClient).EC2Conn(ctx) - InstanceConnectEndpoint, err := FindInstanceConnectEndpointByName(ctx, conn, d.Id()) + output, err := conn.DescribeInstanceConnectEndpointsWithContext(ctx, &ec2.DescribeInstanceConnectEndpointsInput{ + InstanceConnectEndpointIds: []*string{aws.String(d.Id())}, + }) if !d.IsNewResource() && tfresource.NotFound(err) { - log.Printf("[WARN] EC2 Key Pair (%s) not found, removing from state", d.Id()) + create.LogNotFoundRemoveState(names.EC2, create.ErrActionReading, ResInstanceConnectEndpointState, d.Id()) d.SetId("") - return diags + return nil } if err != nil { - return sdkdiag.AppendErrorf(diags, "reading EC2 Key Pair (%s): %s", d.Id(), err) + return create.DiagError(names.EC2, create.ErrActionReading, ResInstanceConnectEndpointState, d.Id(), err) + } + + d.Set("id", output.InstanceConnectEndpoints[0].InstanceConnectEndpointId) + d.Set("arn", output.InstanceConnectEndpoints[0].InstanceConnectEndpointArn) + + d.Set("availability_zone", output.InstanceConnectEndpoints[0].AvailabilityZone) + d.Set("created_at", output.InstanceConnectEndpoints[0].CreatedAt) + d.Set("dns_name", output.InstanceConnectEndpoints[0].DnsName) + d.Set("fips_dns_name", output.InstanceConnectEndpoints[0].FipsDnsName) + + if err := d.Set("network_interface_ids", flex.FlattenStringSet(output.InstanceConnectEndpoints[0].NetworkInterfaceIds)); err != nil { + return sdkdiag.AppendErrorf(diags, "setting network_interface_ids for EC2 Instance Connect Endpoint (%s): %s", d.Id(), err) } - arn := arn.ARN{ - Partition: meta.(*conns.AWSClient).Partition, - Service: ec2.ServiceName, - Region: meta.(*conns.AWSClient).Region, - AccountID: meta.(*conns.AWSClient).AccountID, - Resource: fmt.Sprintf("key-pair/%s", d.Id()), - }.String() + d.Set("owner_id", output.InstanceConnectEndpoints[0].OwnerId) + d.Set("preserve_client_ip", output.InstanceConnectEndpoints[0].PreserveClientIp) - d.Set("arn", arn) - d.Set("fingerprint", InstanceConnectEndpoint.KeyFingerprint) - d.Set("key_name", InstanceConnectEndpoint.KeyName) - d.Set("key_name_prefix", create.NamePrefixFromName(aws.StringValue(InstanceConnectEndpoint.KeyName))) - d.Set("key_type", InstanceConnectEndpoint.KeyType) - d.Set("key_pair_id", InstanceConnectEndpoint.InstanceConnectEndpointId) + if err := d.Set("security_group_ids", flex.FlattenStringSet(output.InstanceConnectEndpoints[0].SecurityGroupIds)); err != nil { + return sdkdiag.AppendErrorf(diags, "setting security_group_ids for EC2 Instance Connect Endpoint (%s): %s", d.Id(), err) + } - setTagsOut(ctx, InstanceConnectEndpoint.Tags) + d.Set("state", output.InstanceConnectEndpoints[0].State) + d.Set("subnet_id", output.InstanceConnectEndpoints[0].SubnetId) + d.Set("vpc_id", output.InstanceConnectEndpoints[0].VpcId) + setTagsOut(ctx, output.InstanceConnectEndpoints[0].Tags) return diags } @@ -113,7 +180,6 @@ func resourceInstanceConnectEndpointUpdate(ctx context.Context, d *schema.Resour var diags diag.Diagnostics // Tags only. - return append(diags, resourceInstanceConnectEndpointRead(ctx, d, meta)...) } @@ -121,13 +187,13 @@ func resourceInstanceConnectEndpointDelete(ctx context.Context, d *schema.Resour var diags diag.Diagnostics conn := meta.(*conns.AWSClient).EC2Conn(ctx) - log.Printf("[DEBUG] Deleting EC2 Key Pair: %s", d.Id()) + log.Printf("[DEBUG] Deleting EC2 Instance Connect Endpoint: %s", d.Id()) _, err := conn.DeleteInstanceConnectEndpointWithContext(ctx, &ec2.DeleteInstanceConnectEndpointInput{ - KeyName: aws.String(d.Id()), + InstanceConnectEndpointId: aws.String(d.Id()), }) if err != nil { - return sdkdiag.AppendErrorf(diags, "deleting EC2 Key Pair (%s): %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "deleting EC2 Instance Connect Endpoint (%s): %s", d.Id(), err) } return diags From bbcc0bbcc81beab897938c6b963d7ca587f6b0d2 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Mon, 19 Jun 2023 21:24:41 +0200 Subject: [PATCH 6/7] Create 32011.txt --- .changelog/32011.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/32011.txt diff --git a/.changelog/32011.txt b/.changelog/32011.txt new file mode 100644 index 000000000000..c230ca7f025a --- /dev/null +++ b/.changelog/32011.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_ec2_instance_connect_endpoint +``` From 332507005024cad8b4192cc46eeb5685db12994e Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Mon, 19 Jun 2023 21:36:43 +0200 Subject: [PATCH 7/7] Create ec2_instance_connect_endpoint_test.go --- .../ec2/ec2_instance_connect_endpoint_test.go | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 internal/service/ec2/ec2_instance_connect_endpoint_test.go diff --git a/internal/service/ec2/ec2_instance_connect_endpoint_test.go b/internal/service/ec2/ec2_instance_connect_endpoint_test.go new file mode 100644 index 000000000000..81ffbcd84668 --- /dev/null +++ b/internal/service/ec2/ec2_instance_connect_endpoint_test.go @@ -0,0 +1,47 @@ +package ec2_test + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/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 TestAccEC2InstanceConnectEndpoint_basic(t *testing.T) { + ctx := acctest.Context(t) + resourceName := "aws_ec2_instance_connect_endpoint.test" + vpcResourceName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckInstanceDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccInstanceConnectEndpointConfig_basic(vpcResourceName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(resourceName, "instance_id"), + resource.TestCheckResourceAttr(resourceName, "state", state), + ), + }, + }, + }) +} + +func testAccInstanceConnectEndpointConfig_basic(vpcResourceName) string { + return acctest.ConfigCompose( + acctest.ConfigVPCWithSubnets(vpcResourceName, 1), + fmt.Sprintf(` +resource "aws_ec2_instance_connect_endpoint" "test" { + subnet_id = aws_subnet.test[0].id +} +`)) +}