From 24c2de21a7231138a5b9826d2533b66a661c7a75 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Sun, 2 Jul 2023 14:33:58 -0400 Subject: [PATCH 01/19] worksapces: Add connection_alias --- .../service/workspaces/connection_alias.go | 279 ++++++++++++++++++ .../workspaces/connection_alias_test.go | 201 +++++++++++++ .../workspaces_connection_alias.html.markdown | 60 ++++ ...s_workspace_connection_alias.html.markdown | 60 ++++ 4 files changed, 600 insertions(+) create mode 100644 internal/service/workspaces/connection_alias.go create mode 100644 internal/service/workspaces/connection_alias_test.go create mode 100644 website/docs/r/workspaces_connection_alias.html.markdown create mode 100644 website/docs/r/workspaces_workspace_connection_alias.html.markdown diff --git a/internal/service/workspaces/connection_alias.go b/internal/service/workspaces/connection_alias.go new file mode 100644 index 000000000000..d6b928ef2034 --- /dev/null +++ b/internal/service/workspaces/connection_alias.go @@ -0,0 +1,279 @@ +package workspaces + +import ( + "context" + "errors" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/workspaces" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkResource(name="Connection Alias") +// @Tags(identifierAttribute="id") +func newResourceConnectionAlias(_ context.Context) (resource.ResourceWithConfigure, error) { + r := &resourceConnectionAlias{} + + r.SetDefaultCreateTimeout(30 * time.Minute) + r.SetDefaultUpdateTimeout(30 * time.Minute) + r.SetDefaultDeleteTimeout(30 * time.Minute) + + return r, nil +} + +const ( + ResNameConnectionAlias = "Connection Alias" +) + +type resourceConnectionAlias struct { + framework.ResourceWithConfigure + framework.WithTimeouts +} + +func (r *resourceConnectionAlias) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "aws_workspaces_connection_alias" +} + +func (r *resourceConnectionAlias) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": framework.IDAttribute(), + "connection_string": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "owner_account_id": schema.StringAttribute{ + Computed: true, + }, + "state": schema.StringAttribute{ + Computed: true, + }, + names.AttrTags: tftags.TagsAttribute(), + names.AttrTagsAll: tftags.TagsAttributeComputedOnly(), + }, + Blocks: map[string]schema.Block{ + "timeouts": timeouts.Block(ctx, timeouts.Opts{ + Create: true, + Update: true, + Delete: true, + }), + }, + } +} + +func (r *resourceConnectionAlias) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + conn := r.Meta().WorkSpacesConn(ctx) + + var plan resourceConnectionAliasData + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + in := &workspaces.CreateConnectionAliasInput{ + ConnectionString: aws.String(plan.ConnectionString.ValueString()), + Tags: getTagsIn(ctx), + } + + out, err := conn.CreateConnectionAliasWithContext(ctx, in) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.WorkSpaces, create.ErrActionCreating, ResNameConnectionAlias, plan.ConnectionString.String(), err), + err.Error(), + ) + return + } + if out == nil || out.AliasId == nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.WorkSpaces, create.ErrActionCreating, ResNameConnectionAlias, plan.ConnectionString.String(), nil), + errors.New("empty output").Error(), + ) + return + } + + plan.ID = flex.StringToFramework(ctx, out.AliasId) + + createTimeout := r.CreateTimeout(ctx, plan.Timeouts) + _, err = waitConnectionAliasCreated(ctx, conn, plan.ID.ValueString(), createTimeout) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.WorkSpaces, create.ErrActionWaitingForCreation, ResNameConnectionAlias, plan.ID.String(), err), + err.Error(), + ) + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) +} + +func (r *resourceConnectionAlias) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + conn := r.Meta().WorkSpacesConn(ctx) + + var state resourceConnectionAliasData + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + out, err := FindConnectionAliasByID(ctx, conn, state.ID.ValueString()) + if tfresource.NotFound(err) { + resp.State.RemoveResource(ctx) + return + } + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.WorkSpaces, create.ErrActionSetting, ResNameConnectionAlias, state.ID.String(), err), + err.Error(), + ) + return + } + + state.ConnectionString = flex.StringToFramework(ctx, out.ConnectionString) + state.OwnerAccountId = flex.StringToFramework(ctx, out.OwnerAccountId) + state.State = flex.StringToFramework(ctx, out.State) + + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (r *resourceConnectionAlias) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { +} + +func (r *resourceConnectionAlias) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + conn := r.Meta().WorkSpacesConn(ctx) + + var state resourceConnectionAliasData + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + in := &workspaces.DeleteConnectionAliasInput{ + AliasId: aws.String(state.ID.ValueString()), + } + + _, err := conn.DeleteConnectionAliasWithContext(ctx, in) + if err != nil { + if tfawserr.ErrCodeEquals(err, workspaces.ErrCodeResourceNotFoundException) { + return + } + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.WorkSpaces, create.ErrActionDeleting, ResNameConnectionAlias, state.ID.String(), err), + err.Error(), + ) + return + } + + deleteTimeout := r.DeleteTimeout(ctx, state.Timeouts) + _, err = waitConnectionAliasDeleted(ctx, conn, state.ID.ValueString(), deleteTimeout) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.WorkSpaces, create.ErrActionWaitingForDeletion, ResNameConnectionAlias, state.ID.String(), err), + err.Error(), + ) + return + } +} + +func (r *resourceConnectionAlias) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} + +func waitConnectionAliasCreated(ctx context.Context, conn *workspaces.WorkSpaces, id string, timeout time.Duration) (*workspaces.ConnectionAlias, error) { + stateConf := &retry.StateChangeConf{ + Pending: []string{workspaces.ConnectionAliasStateCreating}, + Target: []string{workspaces.ConnectionAliasStateCreated}, + Refresh: statusConnectionAlias(ctx, conn, id), + Timeout: timeout, + NotFoundChecks: 20, + ContinuousTargetOccurence: 2, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + if out, ok := outputRaw.(*workspaces.ConnectionAlias); ok { + return out, err + } + + return nil, err +} + +func waitConnectionAliasDeleted(ctx context.Context, conn *workspaces.WorkSpaces, id string, timeout time.Duration) (*workspaces.ConnectionAlias, error) { + stateConf := &retry.StateChangeConf{ + Pending: []string{workspaces.ConnectionAliasStateDeleting}, + Target: []string{}, + Refresh: statusConnectionAlias(ctx, conn, id), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + if out, ok := outputRaw.(*workspaces.ConnectionAlias); ok { + return out, err + } + + return nil, err +} + +func statusConnectionAlias(ctx context.Context, conn *workspaces.WorkSpaces, id string) retry.StateRefreshFunc { + return func() (interface{}, string, error) { + out, err := FindConnectionAliasByID(ctx, conn, id) + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return out, aws.StringValue(out.State), nil + } +} + +func FindConnectionAliasByID(ctx context.Context, conn *workspaces.WorkSpaces, id string) (*workspaces.ConnectionAlias, error) { + in := &workspaces.DescribeConnectionAliasesInput{ + AliasIds: aws.StringSlice([]string{id}), + } + + out, err := conn.DescribeConnectionAliasesWithContext(ctx, in) + if tfawserr.ErrCodeEquals(err, workspaces.ErrCodeResourceNotFoundException) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: in, + } + } + + if err != nil { + return nil, err + } + + if out == nil || len(out.ConnectionAliases) == 0 { + return nil, tfresource.NewEmptyResultError(in) + } + + return out.ConnectionAliases[0], nil +} + +type resourceConnectionAliasData struct { + ID types.String `tfsdk:"id"` + ConnectionString types.String `tfsdk:"name"` + OwnerAccountId types.String `tfsdk:"owner_account_id"` + State types.String `tfsdk:"state"` + Tags types.Map `tfsdk:"tags"` + TagsAll types.Map `tfsdk:"tags_all"` + Timeouts timeouts.Value `tfsdk:"timeouts"` +} diff --git a/internal/service/workspaces/connection_alias_test.go b/internal/service/workspaces/connection_alias_test.go new file mode 100644 index 000000000000..c683d0bc312c --- /dev/null +++ b/internal/service/workspaces/connection_alias_test.go @@ -0,0 +1,201 @@ +package workspaces_test + +import ( + "context" + "errors" + "fmt" + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/workspaces" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "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" + "github.com/hashicorp/terraform-provider-aws/internal/create" + tfworkspaces "github.com/hashicorp/terraform-provider-aws/internal/service/workspaces" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccWorkSpacesConnectionAlias_basic(t *testing.T) { + ctx := acctest.Context(t) + + var connectionalias workspaces.ConnectionAlias + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_workspaces_connection_alias.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, workspaces.EndpointsID) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, workspaces.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckConnectionAliasDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccConnectionAliasConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckConnectionAliasExists(ctx, resourceName, &connectionalias), + resource.TestCheckResourceAttr(resourceName, "connec", "false"), + resource.TestCheckResourceAttrSet(resourceName, "maintenance_window_start_time.0.day_of_week"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "user.*", map[string]string{ + "console_access": "false", + "groups.#": "0", + "username": "Test", + "password": "TestTest1234", + }), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "workspaces", regexp.MustCompile(`connectionalias:+.`)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"apply_immediately", "user"}, + }, + }, + }) +} + +func TestAccWorkSpacesConnectionAlias_disappears(t *testing.T) { + ctx := acctest.Context(t) + + var connectionalias workspaces.ConnectionAlias + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_workspaces_connection_alias.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, workspaces.EndpointsID) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, workspaces.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckConnectionAliasDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccConnectionAliasConfig_basic(rName, testAccConnectionAliasVersionNewer), + Check: resource.ComposeTestCheckFunc( + testAccCheckConnectionAliasExists(ctx, resourceName, &connectionalias), + // TIP: The Plugin-Framework disappears helper is similar to the Plugin-SDK version, + // but expects a new resource factory function as the third argument. To expose this + // private function to the testing package, you may need to add a line like the following + // to exports_test.go: + // + // var ResourceConnectionAlias = newResourceConnectionAlias + acctest.CheckFrameworkResourceDisappears(ctx, acctest.Provider, tfworkspaces.ResourceConnectionAlias, resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckConnectionAliasDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).WorkSpacesConn(ctx) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_workspaces_connection_alias" { + continue + } + + _, err := tfworkspaces.FindConnectionAliasByID(ctx, conn, rs.Primary.ID) + + if tfresource.NotFound(err) { + return nil + } + + if err != nil { + return nil + } + + return create.Error(names.WorkSpaces, create.ErrActionCheckingDestroyed, tfworkspaces.ResNameConnectionAlias, rs.Primary.ID, errors.New("not destroyed")) + } + + return nil + } +} + +func testAccCheckConnectionAliasExists(ctx context.Context, name string, connectionalias *workspaces.ConnectionAlias) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return create.Error(names.WorkSpaces, create.ErrActionCheckingExistence, tfworkspaces.ResNameConnectionAlias, name, errors.New("not found")) + } + + if rs.Primary.ID == "" { + return create.Error(names.WorkSpaces, create.ErrActionCheckingExistence, tfworkspaces.ResNameConnectionAlias, name, errors.New("not set")) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).WorkSpacesConn(ctx) + out, err := tfworkspaces.FindConnectionAliasByID(ctx, conn, rs.Primary.ID) + + if err != nil { + return create.Error(names.WorkSpaces, create.ErrActionCheckingExistence, tfworkspaces.ResNameConnectionAlias, rs.Primary.ID, err) + } + + *connectionalias = *out + + return nil + } +} + +func testAccPreCheck(ctx context.Context, t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).WorkSpacesConn(ctx) + + input := &workspaces.DescribeConnectionAliasesInput{} + _, err := conn.DescribeConnectionAliasesWithContext(ctx, input) + + if acctest.PreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) + } + if err != nil { + t.Fatalf("unexpected PreCheck error: %s", err) + } +} + +func testAccCheckConnectionAliasNotRecreated(before, after *workspaces.ConnectionAlias) resource.TestCheckFunc { + return func(s *terraform.State) error { + if before, after := aws.StringValue(before.AliasId), aws.StringValue(after.AliasId); before != after { + return create.Error(names.WorkSpaces, create.ErrActionCheckingNotRecreated, tfworkspaces.ResNameConnectionAlias, before, errors.New("recreated")) + } + + return nil + } +} + +func testAccConnectionAliasConfig_basic(rName, domain, workspaceName string) string { + return acctest.ConfigCompose( + testAccWorkspaceConfig_Prerequisites(rName, domain), + fmt.Sprintf(` +resource "aws_security_group" "test" { + name = %[1]q +} + +resource "aws_workspaces_connection_alias" "test" { + connection_alias_name = %[1]q + engine_type = "ActiveWorkSpaces" + engine_version = %[2]q + host_instance_type = "workspaces.t2.micro" + security_groups = [aws_security_group.test.id] + authentication_strategy = "simple" + storage_type = "efs" + + logs { + general = true + } + + user { + username = "Test" + password = "TestTest1234" + } +} +`, rName, domain)) +} diff --git a/website/docs/r/workspaces_connection_alias.html.markdown b/website/docs/r/workspaces_connection_alias.html.markdown new file mode 100644 index 000000000000..eb1cddfc9297 --- /dev/null +++ b/website/docs/r/workspaces_connection_alias.html.markdown @@ -0,0 +1,60 @@ +--- +subcategory: "WorkSpaces" +layout: "aws" +page_title: "AWS: aws_workspaces_connection_alias" +description: |- + Terraform resource for managing an AWS WorkSpaces Connection Alias. +--- +` +# Resource: aws_workspaces_connection_alias + +Terraform resource for managing an AWS WorkSpaces Connection Alias. + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_workspaces_connection_alias" "example" { +} +``` + +## Argument Reference + +The following arguments are required: + +* `example_arg` - (Required) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. + +The following arguments are optional: + +* `optional_arg` - (Optional) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - ARN of the Connection Alias. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. +* `example_attribute` - Concise description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. + +## Timeouts + +[Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): + +* `create` - (Default `60m`) +* `update` - (Default `180m`) +* `delete` - (Default `90m`) + +## Import + +WorkSpaces Connection Alias can be imported using the `example_id_arg`, e.g., + +``` +$ terraform import aws_workspaces_connection_alias.example rft-8012925589 +``` diff --git a/website/docs/r/workspaces_workspace_connection_alias.html.markdown b/website/docs/r/workspaces_workspace_connection_alias.html.markdown new file mode 100644 index 000000000000..51c946126d61 --- /dev/null +++ b/website/docs/r/workspaces_workspace_connection_alias.html.markdown @@ -0,0 +1,60 @@ +--- +subcategory: "WorkSpaces" +layout: "aws" +page_title: "AWS: aws_workspaces_workspace_connection_alias" +description: |- + Terraform resource for managing an AWS WorkSpaces Workspace Connection Alias. +--- +` +# Resource: aws_workspaces_workspace_connection_alias + +Terraform resource for managing an AWS WorkSpaces Workspace Connection Alias. + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_workspaces_workspace_connection_alias" "example" { +} +``` + +## Argument Reference + +The following arguments are required: + +* `example_arg` - (Required) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. + +The following arguments are optional: + +* `optional_arg` - (Optional) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - ARN of the Workspace Connection Alias. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. +* `example_attribute` - Concise description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. + +## Timeouts + +[Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): + +* `create` - (Default `60m`) +* `update` - (Default `180m`) +* `delete` - (Default `90m`) + +## Import + +WorkSpaces Workspace Connection Alias can be imported using the `example_id_arg`, e.g., + +``` +$ terraform import aws_workspaces_workspace_connection_alias.example rft-8012925589 +``` From c3e8f96dd226d96d6486a1c5ae22fc5c1ad50e48 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:29:45 -0400 Subject: [PATCH 02/19] website: Remove extra workspaces_workspace_connection_alias --- ...s_workspace_connection_alias.html.markdown | 60 ------------------- 1 file changed, 60 deletions(-) delete mode 100644 website/docs/r/workspaces_workspace_connection_alias.html.markdown diff --git a/website/docs/r/workspaces_workspace_connection_alias.html.markdown b/website/docs/r/workspaces_workspace_connection_alias.html.markdown deleted file mode 100644 index 51c946126d61..000000000000 --- a/website/docs/r/workspaces_workspace_connection_alias.html.markdown +++ /dev/null @@ -1,60 +0,0 @@ ---- -subcategory: "WorkSpaces" -layout: "aws" -page_title: "AWS: aws_workspaces_workspace_connection_alias" -description: |- - Terraform resource for managing an AWS WorkSpaces Workspace Connection Alias. ---- -` -# Resource: aws_workspaces_workspace_connection_alias - -Terraform resource for managing an AWS WorkSpaces Workspace Connection Alias. - -## Example Usage - -### Basic Usage - -```terraform -resource "aws_workspaces_workspace_connection_alias" "example" { -} -``` - -## Argument Reference - -The following arguments are required: - -* `example_arg` - (Required) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. - -The following arguments are optional: - -* `optional_arg` - (Optional) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. - -## Attributes Reference - -In addition to all arguments above, the following attributes are exported: - -* `arn` - ARN of the Workspace Connection Alias. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. -* `example_attribute` - Concise description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. - -## Timeouts - -[Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): - -* `create` - (Default `60m`) -* `update` - (Default `180m`) -* `delete` - (Default `90m`) - -## Import - -WorkSpaces Workspace Connection Alias can be imported using the `example_id_arg`, e.g., - -``` -$ terraform import aws_workspaces_workspace_connection_alias.example rft-8012925589 -``` From 758da5a1e1d936a626e2d5f131967f47eeb05efc Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:31:08 -0400 Subject: [PATCH 03/19] website: Amend workspaces_connection_alis, Update docs with proper fields and values --- .../workspaces_connection_alias.html.markdown | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/website/docs/r/workspaces_connection_alias.html.markdown b/website/docs/r/workspaces_connection_alias.html.markdown index eb1cddfc9297..913437dd9610 100644 --- a/website/docs/r/workspaces_connection_alias.html.markdown +++ b/website/docs/r/workspaces_connection_alias.html.markdown @@ -5,14 +5,7 @@ page_title: "AWS: aws_workspaces_connection_alias" description: |- Terraform resource for managing an AWS WorkSpaces Connection Alias. --- -` + # Resource: aws_workspaces_connection_alias Terraform resource for managing an AWS WorkSpaces Connection Alias. @@ -23,6 +16,7 @@ Terraform resource for managing an AWS WorkSpaces Connection Alias. ```terraform resource "aws_workspaces_connection_alias" "example" { + connection_string = "testdomain.test" } ``` @@ -30,18 +24,17 @@ resource "aws_workspaces_connection_alias" "example" { The following arguments are required: -* `example_arg` - (Required) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. - -The following arguments are optional: - -* `optional_arg` - (Optional) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. +* `connection_string` - (Required) The connection string specified for the connection alias. The connection string must be in the form of a fully qualified domain name (FQDN), such as www.example.com. +* `tags` – (Optional) A map of tags assigned to the WorkSpaces Connection Alias. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attributes Reference In addition to all arguments above, the following attributes are exported: -* `arn` - ARN of the Connection Alias. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. -* `example_attribute` - Concise description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. +* `id` - The identifier of the connection alias. +* `owner_account_id` - The identifier of the Amazon Web Services account that owns the connection alias. +* `state` - The current state of the connection alias. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block). ## Timeouts @@ -53,7 +46,7 @@ In addition to all arguments above, the following attributes are exported: ## Import -WorkSpaces Connection Alias can be imported using the `example_id_arg`, e.g., +WorkSpaces Connection Alias can be imported using the `id`, e.g., ``` $ terraform import aws_workspaces_connection_alias.example rft-8012925589 From dc8fa8984ed316a2fc01f2eafd55251812b4f251 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:32:08 -0400 Subject: [PATCH 04/19] workspaces: Amend connection_alias, update to aws-sdk-go-v2 --- .../service/workspaces/connection_alias.go | 74 +++++++++++-------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/internal/service/workspaces/connection_alias.go b/internal/service/workspaces/connection_alias.go index d6b928ef2034..9c3a4339ef88 100644 --- a/internal/service/workspaces/connection_alias.go +++ b/internal/service/workspaces/connection_alias.go @@ -5,9 +5,9 @@ import ( "errors" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/workspaces" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/workspaces" + awstypes "github.com/aws/aws-sdk-go-v2/service/workspaces/types" "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -17,6 +17,8 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/enum" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/framework" "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" @@ -24,6 +26,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) +var ResourceConnectionAlias = newResourceConnectionAlias + // @FrameworkResource(name="Connection Alias") // @Tags(identifierAttribute="id") func newResourceConnectionAlias(_ context.Context) (resource.ResourceWithConfigure, error) { @@ -58,12 +62,15 @@ func (r *resourceConnectionAlias) Schema(ctx context.Context, req resource.Schem PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), }, + Description: "The connection string specified for the connection alias. The connection string must be in the form of a fully qualified domain name (FQDN), such as www.example.com.", }, "owner_account_id": schema.StringAttribute{ - Computed: true, + Computed: true, + Description: "The identifier of the Amazon Web Services account that owns the connection alias.", }, "state": schema.StringAttribute{ - Computed: true, + Computed: true, + Description: "The current state of the connection alias.", }, names.AttrTags: tftags.TagsAttribute(), names.AttrTagsAll: tftags.TagsAttributeComputedOnly(), @@ -71,7 +78,6 @@ func (r *resourceConnectionAlias) Schema(ctx context.Context, req resource.Schem Blocks: map[string]schema.Block{ "timeouts": timeouts.Block(ctx, timeouts.Opts{ Create: true, - Update: true, Delete: true, }), }, @@ -79,7 +85,7 @@ func (r *resourceConnectionAlias) Schema(ctx context.Context, req resource.Schem } func (r *resourceConnectionAlias) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - conn := r.Meta().WorkSpacesConn(ctx) + conn := r.Meta().WorkSpacesClient(ctx) var plan resourceConnectionAliasData resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) @@ -92,7 +98,7 @@ func (r *resourceConnectionAlias) Create(ctx context.Context, req resource.Creat Tags: getTagsIn(ctx), } - out, err := conn.CreateConnectionAliasWithContext(ctx, in) + out, err := conn.CreateConnectionAlias(ctx, in) if err != nil { resp.Diagnostics.AddError( create.ProblemStandardMessage(names.WorkSpaces, create.ErrActionCreating, ResNameConnectionAlias, plan.ConnectionString.String(), err), @@ -111,7 +117,7 @@ func (r *resourceConnectionAlias) Create(ctx context.Context, req resource.Creat plan.ID = flex.StringToFramework(ctx, out.AliasId) createTimeout := r.CreateTimeout(ctx, plan.Timeouts) - _, err = waitConnectionAliasCreated(ctx, conn, plan.ID.ValueString(), createTimeout) + alias, err := waitConnectionAliasCreated(ctx, conn, plan.ID.ValueString(), createTimeout) if err != nil { resp.Diagnostics.AddError( create.ProblemStandardMessage(names.WorkSpaces, create.ErrActionWaitingForCreation, ResNameConnectionAlias, plan.ID.String(), err), @@ -120,11 +126,12 @@ func (r *resourceConnectionAlias) Create(ctx context.Context, req resource.Creat return } + plan.update(ctx, alias) resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) } func (r *resourceConnectionAlias) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - conn := r.Meta().WorkSpacesConn(ctx) + conn := r.Meta().WorkSpacesClient(ctx) var state resourceConnectionAliasData resp.Diagnostics.Append(req.State.Get(ctx, &state)...) @@ -145,9 +152,7 @@ func (r *resourceConnectionAlias) Read(ctx context.Context, req resource.ReadReq return } - state.ConnectionString = flex.StringToFramework(ctx, out.ConnectionString) - state.OwnerAccountId = flex.StringToFramework(ctx, out.OwnerAccountId) - state.State = flex.StringToFramework(ctx, out.State) + state.update(ctx, out) resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) } @@ -156,7 +161,7 @@ func (r *resourceConnectionAlias) Update(ctx context.Context, req resource.Updat } func (r *resourceConnectionAlias) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - conn := r.Meta().WorkSpacesConn(ctx) + conn := r.Meta().WorkSpacesClient(ctx) var state resourceConnectionAliasData resp.Diagnostics.Append(req.State.Get(ctx, &state)...) @@ -168,9 +173,9 @@ func (r *resourceConnectionAlias) Delete(ctx context.Context, req resource.Delet AliasId: aws.String(state.ID.ValueString()), } - _, err := conn.DeleteConnectionAliasWithContext(ctx, in) + _, err := conn.DeleteConnectionAlias(ctx, in) if err != nil { - if tfawserr.ErrCodeEquals(err, workspaces.ErrCodeResourceNotFoundException) { + if errs.IsA[*awstypes.ResourceNotFoundException](err) { return } resp.Diagnostics.AddError( @@ -195,10 +200,16 @@ func (r *resourceConnectionAlias) ImportState(ctx context.Context, req resource. resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) } -func waitConnectionAliasCreated(ctx context.Context, conn *workspaces.WorkSpaces, id string, timeout time.Duration) (*workspaces.ConnectionAlias, error) { +func (data *resourceConnectionAliasData) update(ctx context.Context, in *awstypes.ConnectionAlias) { + data.ConnectionString = flex.StringToFramework(ctx, in.ConnectionString) + data.OwnerAccountId = flex.StringToFramework(ctx, in.OwnerAccountId) + data.State = flex.StringValueToFramework(ctx, in.State) +} + +func waitConnectionAliasCreated(ctx context.Context, conn *workspaces.Client, id string, timeout time.Duration) (*awstypes.ConnectionAlias, error) { stateConf := &retry.StateChangeConf{ - Pending: []string{workspaces.ConnectionAliasStateCreating}, - Target: []string{workspaces.ConnectionAliasStateCreated}, + Pending: enum.Slice(awstypes.ConnectionAliasStateCreating), + Target: enum.Slice(awstypes.ConnectionAliasStateCreated), Refresh: statusConnectionAlias(ctx, conn, id), Timeout: timeout, NotFoundChecks: 20, @@ -206,30 +217,30 @@ func waitConnectionAliasCreated(ctx context.Context, conn *workspaces.WorkSpaces } outputRaw, err := stateConf.WaitForStateContext(ctx) - if out, ok := outputRaw.(*workspaces.ConnectionAlias); ok { + if out, ok := outputRaw.(*awstypes.ConnectionAlias); ok { return out, err } return nil, err } -func waitConnectionAliasDeleted(ctx context.Context, conn *workspaces.WorkSpaces, id string, timeout time.Duration) (*workspaces.ConnectionAlias, error) { +func waitConnectionAliasDeleted(ctx context.Context, conn *workspaces.Client, id string, timeout time.Duration) (*awstypes.ConnectionAlias, error) { stateConf := &retry.StateChangeConf{ - Pending: []string{workspaces.ConnectionAliasStateDeleting}, + Pending: enum.Slice(awstypes.ConnectionAliasStateDeleting), Target: []string{}, Refresh: statusConnectionAlias(ctx, conn, id), Timeout: timeout, } outputRaw, err := stateConf.WaitForStateContext(ctx) - if out, ok := outputRaw.(*workspaces.ConnectionAlias); ok { + if out, ok := outputRaw.(*awstypes.ConnectionAlias); ok { return out, err } return nil, err } -func statusConnectionAlias(ctx context.Context, conn *workspaces.WorkSpaces, id string) retry.StateRefreshFunc { +func statusConnectionAlias(ctx context.Context, conn *workspaces.Client, id string) retry.StateRefreshFunc { return func() (interface{}, string, error) { out, err := FindConnectionAliasByID(ctx, conn, id) if tfresource.NotFound(err) { @@ -240,17 +251,18 @@ func statusConnectionAlias(ctx context.Context, conn *workspaces.WorkSpaces, id return nil, "", err } - return out, aws.StringValue(out.State), nil + return out, string(out.State), nil } } -func FindConnectionAliasByID(ctx context.Context, conn *workspaces.WorkSpaces, id string) (*workspaces.ConnectionAlias, error) { +func FindConnectionAliasByID(ctx context.Context, conn *workspaces.Client, id string) (*awstypes.ConnectionAlias, error) { in := &workspaces.DescribeConnectionAliasesInput{ - AliasIds: aws.StringSlice([]string{id}), + AliasIds: []string{id}, } - out, err := conn.DescribeConnectionAliasesWithContext(ctx, in) - if tfawserr.ErrCodeEquals(err, workspaces.ErrCodeResourceNotFoundException) { + out, err := conn.DescribeConnectionAliases(ctx, in) + + if errs.IsA[*awstypes.ResourceNotFoundException](err) { return nil, &retry.NotFoundError{ LastError: err, LastRequest: in, @@ -265,12 +277,12 @@ func FindConnectionAliasByID(ctx context.Context, conn *workspaces.WorkSpaces, i return nil, tfresource.NewEmptyResultError(in) } - return out.ConnectionAliases[0], nil + return &out.ConnectionAliases[0], nil } type resourceConnectionAliasData struct { ID types.String `tfsdk:"id"` - ConnectionString types.String `tfsdk:"name"` + ConnectionString types.String `tfsdk:"connection_string"` OwnerAccountId types.String `tfsdk:"owner_account_id"` State types.String `tfsdk:"state"` Tags types.Map `tfsdk:"tags"` From 4f16e025a396fcfc36e3fbbd4fd75d509447a548 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:32:23 -0400 Subject: [PATCH 05/19] workspaces: Amend connection_alias_test, update to aws-sdk-go-v2 --- .../workspaces/connection_alias_test.go | 100 ++++++------------ 1 file changed, 33 insertions(+), 67 deletions(-) diff --git a/internal/service/workspaces/connection_alias_test.go b/internal/service/workspaces/connection_alias_test.go index c683d0bc312c..0be12ccfea53 100644 --- a/internal/service/workspaces/connection_alias_test.go +++ b/internal/service/workspaces/connection_alias_test.go @@ -4,12 +4,12 @@ import ( "context" "errors" "fmt" - "regexp" + "strings" "testing" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/workspaces" - sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/workspaces" + awstypes "github.com/aws/aws-sdk-go-v2/service/workspaces/types" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" @@ -20,20 +20,20 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -func TestAccWorkSpacesConnectionAlias_basic(t *testing.T) { +func TestAccWorkspacesClientectionAlias_basic(t *testing.T) { ctx := acctest.Context(t) - var connectionalias workspaces.ConnectionAlias - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + var connectionalias awstypes.ConnectionAlias + rName := acctest.RandomFQDomainName() resourceName := "aws_workspaces_connection_alias.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) - acctest.PreCheckPartitionHasService(t, workspaces.EndpointsID) + acctest.PreCheckPartitionHasService(t, strings.ToLower(workspaces.ServiceID)) testAccPreCheck(ctx, t) }, - ErrorCheck: acctest.ErrorCheck(t, workspaces.EndpointsID), + ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(workspaces.ServiceID)), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckConnectionAliasDestroy(ctx), Steps: []resource.TestStep{ @@ -41,54 +41,41 @@ func TestAccWorkSpacesConnectionAlias_basic(t *testing.T) { Config: testAccConnectionAliasConfig_basic(rName), Check: resource.ComposeTestCheckFunc( testAccCheckConnectionAliasExists(ctx, resourceName, &connectionalias), - resource.TestCheckResourceAttr(resourceName, "connec", "false"), - resource.TestCheckResourceAttrSet(resourceName, "maintenance_window_start_time.0.day_of_week"), - resource.TestCheckTypeSetElemNestedAttrs(resourceName, "user.*", map[string]string{ - "console_access": "false", - "groups.#": "0", - "username": "Test", - "password": "TestTest1234", - }), - acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "workspaces", regexp.MustCompile(`connectionalias:+.`)), + resource.TestCheckResourceAttr(resourceName, "connection_string", rName), + resource.TestCheckResourceAttrSet(resourceName, "owner_account_id"), + resource.TestCheckResourceAttrSet(resourceName, "state"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"apply_immediately", "user"}, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func TestAccWorkSpacesConnectionAlias_disappears(t *testing.T) { +func TestAccWorkspacesClientectionAlias_disappears(t *testing.T) { ctx := acctest.Context(t) - var connectionalias workspaces.ConnectionAlias - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + var connectionalias awstypes.ConnectionAlias + rName := acctest.RandomFQDomainName() resourceName := "aws_workspaces_connection_alias.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) - acctest.PreCheckPartitionHasService(t, workspaces.EndpointsID) - testAccPreCheck(t) + acctest.PreCheckPartitionHasService(t, strings.ToLower(workspaces.ServiceID)) + testAccPreCheck(ctx, t) }, - ErrorCheck: acctest.ErrorCheck(t, workspaces.EndpointsID), + ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(workspaces.ServiceID)), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckConnectionAliasDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccConnectionAliasConfig_basic(rName, testAccConnectionAliasVersionNewer), + Config: testAccConnectionAliasConfig_basic(rName), Check: resource.ComposeTestCheckFunc( testAccCheckConnectionAliasExists(ctx, resourceName, &connectionalias), - // TIP: The Plugin-Framework disappears helper is similar to the Plugin-SDK version, - // but expects a new resource factory function as the third argument. To expose this - // private function to the testing package, you may need to add a line like the following - // to exports_test.go: - // - // var ResourceConnectionAlias = newResourceConnectionAlias acctest.CheckFrameworkResourceDisappears(ctx, acctest.Provider, tfworkspaces.ResourceConnectionAlias, resourceName), ), ExpectNonEmptyPlan: true, @@ -99,7 +86,7 @@ func TestAccWorkSpacesConnectionAlias_disappears(t *testing.T) { func testAccCheckConnectionAliasDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).WorkSpacesConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).WorkSpacesClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_workspaces_connection_alias" { @@ -123,7 +110,7 @@ func testAccCheckConnectionAliasDestroy(ctx context.Context) resource.TestCheckF } } -func testAccCheckConnectionAliasExists(ctx context.Context, name string, connectionalias *workspaces.ConnectionAlias) resource.TestCheckFunc { +func testAccCheckConnectionAliasExists(ctx context.Context, name string, connectionalias *awstypes.ConnectionAlias) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] if !ok { @@ -134,7 +121,7 @@ func testAccCheckConnectionAliasExists(ctx context.Context, name string, connect return create.Error(names.WorkSpaces, create.ErrActionCheckingExistence, tfworkspaces.ResNameConnectionAlias, name, errors.New("not set")) } - conn := acctest.Provider.Meta().(*conns.AWSClient).WorkSpacesConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).WorkSpacesClient(ctx) out, err := tfworkspaces.FindConnectionAliasByID(ctx, conn, rs.Primary.ID) if err != nil { @@ -148,10 +135,10 @@ func testAccCheckConnectionAliasExists(ctx context.Context, name string, connect } func testAccPreCheck(ctx context.Context, t *testing.T) { - conn := acctest.Provider.Meta().(*conns.AWSClient).WorkSpacesConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).WorkSpacesClient(ctx) input := &workspaces.DescribeConnectionAliasesInput{} - _, err := conn.DescribeConnectionAliasesWithContext(ctx, input) + _, err := conn.DescribeConnectionAliases(ctx, input) if acctest.PreCheckSkipError(err) { t.Skipf("skipping acceptance testing: %s", err) @@ -161,9 +148,9 @@ func testAccPreCheck(ctx context.Context, t *testing.T) { } } -func testAccCheckConnectionAliasNotRecreated(before, after *workspaces.ConnectionAlias) resource.TestCheckFunc { +func testAccCheckConnectionAliasNotRecreated(before, after *awstypes.ConnectionAlias) resource.TestCheckFunc { return func(s *terraform.State) error { - if before, after := aws.StringValue(before.AliasId), aws.StringValue(after.AliasId); before != after { + if before, after := aws.ToString(before.AliasId), aws.ToString(after.AliasId); before != after { return create.Error(names.WorkSpaces, create.ErrActionCheckingNotRecreated, tfworkspaces.ResNameConnectionAlias, before, errors.New("recreated")) } @@ -171,31 +158,10 @@ func testAccCheckConnectionAliasNotRecreated(before, after *workspaces.Connectio } } -func testAccConnectionAliasConfig_basic(rName, domain, workspaceName string) string { - return acctest.ConfigCompose( - testAccWorkspaceConfig_Prerequisites(rName, domain), - fmt.Sprintf(` -resource "aws_security_group" "test" { - name = %[1]q -} - +func testAccConnectionAliasConfig_basic(rName string) string { + return fmt.Sprintf(` resource "aws_workspaces_connection_alias" "test" { - connection_alias_name = %[1]q - engine_type = "ActiveWorkSpaces" - engine_version = %[2]q - host_instance_type = "workspaces.t2.micro" - security_groups = [aws_security_group.test.id] - authentication_strategy = "simple" - storage_type = "efs" - - logs { - general = true - } - - user { - username = "Test" - password = "TestTest1234" - } + connection_string = %[1]q } -`, rName, domain)) +`, rName) } From c7453a6caf75227770ec7382a77cfc8c7617061b Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:32:45 -0400 Subject: [PATCH 06/19] workspaces: Amend service_package_gen, make gen --- internal/service/workspaces/service_package_gen.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/service/workspaces/service_package_gen.go b/internal/service/workspaces/service_package_gen.go index 46a3af1b4616..9854cc6c9d81 100644 --- a/internal/service/workspaces/service_package_gen.go +++ b/internal/service/workspaces/service_package_gen.go @@ -19,7 +19,15 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.Serv } func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { - return []*types.ServicePackageFrameworkResource{} + return []*types.ServicePackageFrameworkResource{ + { + Factory: newResourceConnectionAlias, + Name: "Connection Alias", + Tags: &types.ServicePackageResourceTags{ + IdentifierAttribute: "id", + }, + }, + } } func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePackageSDKDataSource { From 5da5902beae393041d8bf6b76b15543ff592b498 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:33:19 -0400 Subject: [PATCH 07/19] Amend GNUmakefile, add lint-fix target to run all lint fix targets --- GNUmakefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GNUmakefile b/GNUmakefile index 92e8a761f963..0141d4c9c9e7 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -189,6 +189,8 @@ importlint: lint: golangci-lint providerlint importlint +lint-fix: testacc-lint-fix website-lint-fix docs-lint-fix + providerlint: @echo "==> Checking source code with providerlint..." @providerlint \ @@ -429,6 +431,7 @@ yamllint: golangci-lint \ importlint \ lint \ + lint-fix \ providerlint \ sane \ sanity \ From 6dc6e6002e8db7fa61d3d5b46c6262612481d23b Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:39:20 -0400 Subject: [PATCH 08/19] workspaces: Amend connection_alias_test, add tags test --- .../workspaces/connection_alias_test.go | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/internal/service/workspaces/connection_alias_test.go b/internal/service/workspaces/connection_alias_test.go index 0be12ccfea53..a144e9ca9869 100644 --- a/internal/service/workspaces/connection_alias_test.go +++ b/internal/service/workspaces/connection_alias_test.go @@ -84,6 +84,57 @@ func TestAccWorkspacesClientectionAlias_disappears(t *testing.T) { }) } +func TestAccWorkspacesClientectionAlias_tags(t *testing.T) { + ctx := acctest.Context(t) + + var connectionalias awstypes.ConnectionAlias + rName := acctest.RandomFQDomainName() + resourceName := "aws_workspaces_connection_alias.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, strings.ToLower(workspaces.ServiceID)) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(workspaces.ServiceID)), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckConnectionAliasDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccConnectionAliasConfig_tags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckConnectionAliasExists(ctx, resourceName, &connectionalias), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccConnectionAliasConfig_tags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckConnectionAliasExists(ctx, resourceName, &connectionalias), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccConnectionAliasConfig_tags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckConnectionAliasExists(ctx, resourceName, &connectionalias), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + func testAccCheckConnectionAliasDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).WorkSpacesClient(ctx) @@ -165,3 +216,28 @@ resource "aws_workspaces_connection_alias" "test" { } `, rName) } + +func testAccConnectionAliasConfig_tags1(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_workspaces_connection_alias" "test" { + connection_string = %[1]q + + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1) +} + +func testAccConnectionAliasConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_workspaces_connection_alias" "test" { + connection_string = %[1]q + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +} From 627d9b99b8a02315b6cf1b47bc142f86270e6a1e Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:19:30 -0400 Subject: [PATCH 09/19] workspaces: Amend connection_alias, add needed update items for tags interceptor --- internal/service/workspaces/connection_alias.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/service/workspaces/connection_alias.go b/internal/service/workspaces/connection_alias.go index 9c3a4339ef88..f313758c5868 100644 --- a/internal/service/workspaces/connection_alias.go +++ b/internal/service/workspaces/connection_alias.go @@ -158,6 +158,13 @@ func (r *resourceConnectionAlias) Read(ctx context.Context, req resource.ReadReq } func (r *resourceConnectionAlias) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan resourceConnectionAliasData + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) } func (r *resourceConnectionAlias) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { From a3c0c7026252494f6aa8971cefc8e55b03b72b35 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:32:16 -0400 Subject: [PATCH 10/19] workspaces: Amend connection_alias, Add copyright? --- internal/service/workspaces/connection_alias.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/service/workspaces/connection_alias.go b/internal/service/workspaces/connection_alias.go index f313758c5868..58f627e6044b 100644 --- a/internal/service/workspaces/connection_alias.go +++ b/internal/service/workspaces/connection_alias.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package workspaces import ( From 83eeb67f4b25501e34b9bc6cc0264d5fc9db8d7e Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:32:51 -0400 Subject: [PATCH 11/19] workspaces: Amend connection_alias_test, add copyright --- internal/service/workspaces/connection_alias_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/service/workspaces/connection_alias_test.go b/internal/service/workspaces/connection_alias_test.go index a144e9ca9869..624bc94b103f 100644 --- a/internal/service/workspaces/connection_alias_test.go +++ b/internal/service/workspaces/connection_alias_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package workspaces_test import ( From 02cdab5e517d9f070024aa0dc01255f7f2cc98d2 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:35:37 -0400 Subject: [PATCH 12/19] workspaces: Amend connection_alias_test, rename test functions --- internal/service/workspaces/connection_alias_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/service/workspaces/connection_alias_test.go b/internal/service/workspaces/connection_alias_test.go index 624bc94b103f..9e957f574bce 100644 --- a/internal/service/workspaces/connection_alias_test.go +++ b/internal/service/workspaces/connection_alias_test.go @@ -23,7 +23,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -func TestAccWorkspacesClientectionAlias_basic(t *testing.T) { +func TestAccWorkspacesConnectionAlias_basic(t *testing.T) { ctx := acctest.Context(t) var connectionalias awstypes.ConnectionAlias @@ -58,7 +58,7 @@ func TestAccWorkspacesClientectionAlias_basic(t *testing.T) { }) } -func TestAccWorkspacesClientectionAlias_disappears(t *testing.T) { +func TestAccWorkspacesConnectionAlias_disappears(t *testing.T) { ctx := acctest.Context(t) var connectionalias awstypes.ConnectionAlias @@ -87,7 +87,7 @@ func TestAccWorkspacesClientectionAlias_disappears(t *testing.T) { }) } -func TestAccWorkspacesClientectionAlias_tags(t *testing.T) { +func TestAccWorkspacesConnectionAlias_tags(t *testing.T) { ctx := acctest.Context(t) var connectionalias awstypes.ConnectionAlias From ac6af47f08d4e05fb532c5888638eb9020c50517 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:38:34 -0400 Subject: [PATCH 13/19] workspaces: Amend connection_alias_test, fix function names --- internal/service/workspaces/connection_alias_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/service/workspaces/connection_alias_test.go b/internal/service/workspaces/connection_alias_test.go index 9e957f574bce..ed7c688fc1d3 100644 --- a/internal/service/workspaces/connection_alias_test.go +++ b/internal/service/workspaces/connection_alias_test.go @@ -23,7 +23,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -func TestAccWorkspacesConnectionAlias_basic(t *testing.T) { +func TestAccWorkSpacesConnectionAlias_basic(t *testing.T) { ctx := acctest.Context(t) var connectionalias awstypes.ConnectionAlias @@ -58,7 +58,7 @@ func TestAccWorkspacesConnectionAlias_basic(t *testing.T) { }) } -func TestAccWorkspacesConnectionAlias_disappears(t *testing.T) { +func TestAccWorkSpacesConnectionAlias_disappears(t *testing.T) { ctx := acctest.Context(t) var connectionalias awstypes.ConnectionAlias @@ -87,7 +87,7 @@ func TestAccWorkspacesConnectionAlias_disappears(t *testing.T) { }) } -func TestAccWorkspacesConnectionAlias_tags(t *testing.T) { +func TestAccWorkSpacesConnectionAlias_tags(t *testing.T) { ctx := acctest.Context(t) var connectionalias awstypes.ConnectionAlias From 2015ad843ea22296bec1df6dd71932d5f0b9e663 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:52:13 -0400 Subject: [PATCH 14/19] workspaces: Amend connection_alias, add UseStateForUnkown for computed fields --- internal/service/workspaces/connection_alias.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/service/workspaces/connection_alias.go b/internal/service/workspaces/connection_alias.go index 58f627e6044b..0bc6be317f32 100644 --- a/internal/service/workspaces/connection_alias.go +++ b/internal/service/workspaces/connection_alias.go @@ -70,10 +70,16 @@ func (r *resourceConnectionAlias) Schema(ctx context.Context, req resource.Schem "owner_account_id": schema.StringAttribute{ Computed: true, Description: "The identifier of the Amazon Web Services account that owns the connection alias.", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, "state": schema.StringAttribute{ Computed: true, Description: "The current state of the connection alias.", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, names.AttrTags: tftags.TagsAttribute(), names.AttrTagsAll: tftags.TagsAttributeComputedOnly(), @@ -81,6 +87,7 @@ func (r *resourceConnectionAlias) Schema(ctx context.Context, req resource.Schem Blocks: map[string]schema.Block{ "timeouts": timeouts.Block(ctx, timeouts.Opts{ Create: true, + Update: true, Delete: true, }), }, From 2555b593ec08ff89f5c4447229c357a1d05c127b Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 15:40:51 -0400 Subject: [PATCH 15/19] workspaces: Amend connection_alias, add ModifyPlan for TagsAll --- internal/service/workspaces/connection_alias.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/service/workspaces/connection_alias.go b/internal/service/workspaces/connection_alias.go index 0bc6be317f32..33d374f4e273 100644 --- a/internal/service/workspaces/connection_alias.go +++ b/internal/service/workspaces/connection_alias.go @@ -168,8 +168,9 @@ func (r *resourceConnectionAlias) Read(ctx context.Context, req resource.ReadReq } func (r *resourceConnectionAlias) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan resourceConnectionAliasData + var plan, state resourceConnectionAliasData resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) if resp.Diagnostics.HasError() { return } @@ -217,6 +218,10 @@ func (r *resourceConnectionAlias) ImportState(ctx context.Context, req resource. resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) } +func (r *resourceConnectionAlias) ModifyPlan(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse) { + r.SetTagsAll(ctx, request, response) +} + func (data *resourceConnectionAliasData) update(ctx context.Context, in *awstypes.ConnectionAlias) { data.ConnectionString = flex.StringToFramework(ctx, in.ConnectionString) data.OwnerAccountId = flex.StringToFramework(ctx, in.OwnerAccountId) From 32d1f5b51f13ea5e2b14bc01a6603a6e0c92bb09 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 15:41:17 -0400 Subject: [PATCH 16/19] workspaces: Amend connection_alias_test, remove un used function --- .../service/workspaces/connection_alias_test.go | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/internal/service/workspaces/connection_alias_test.go b/internal/service/workspaces/connection_alias_test.go index ed7c688fc1d3..0ee49b5cca98 100644 --- a/internal/service/workspaces/connection_alias_test.go +++ b/internal/service/workspaces/connection_alias_test.go @@ -10,7 +10,6 @@ import ( "strings" "testing" - "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/workspaces" awstypes "github.com/aws/aws-sdk-go-v2/service/workspaces/types" "github.com/hashicorp/terraform-plugin-testing/helper/resource" @@ -154,7 +153,7 @@ func testAccCheckConnectionAliasDestroy(ctx context.Context) resource.TestCheckF } if err != nil { - return nil + return err } return create.Error(names.WorkSpaces, create.ErrActionCheckingDestroyed, tfworkspaces.ResNameConnectionAlias, rs.Primary.ID, errors.New("not destroyed")) @@ -202,16 +201,6 @@ func testAccPreCheck(ctx context.Context, t *testing.T) { } } -func testAccCheckConnectionAliasNotRecreated(before, after *awstypes.ConnectionAlias) resource.TestCheckFunc { - return func(s *terraform.State) error { - if before, after := aws.ToString(before.AliasId), aws.ToString(after.AliasId); before != after { - return create.Error(names.WorkSpaces, create.ErrActionCheckingNotRecreated, tfworkspaces.ResNameConnectionAlias, before, errors.New("recreated")) - } - - return nil - } -} - func testAccConnectionAliasConfig_basic(rName string) string { return fmt.Sprintf(` resource "aws_workspaces_connection_alias" "test" { From f08df3290f7c98a930bbf110f533af3bb667b3cf Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 12 Jul 2023 15:42:37 -0400 Subject: [PATCH 17/19] changelog: Add 32482 --- .changelog/32482.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/32482.txt diff --git a/.changelog/32482.txt b/.changelog/32482.txt new file mode 100644 index 000000000000..834c75c2ec08 --- /dev/null +++ b/.changelog/32482.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_workspaces_connection_alias +``` \ No newline at end of file From cc6c58fa055fcf44fcc6c2c3c92d0c8ffbfedf2b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jul 2023 11:31:48 -0400 Subject: [PATCH 18/19] Fix tfproviderdocs error. --- website/docs/r/workspaces_connection_alias.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/workspaces_connection_alias.html.markdown b/website/docs/r/workspaces_connection_alias.html.markdown index 913437dd9610..15d47b0e53c8 100644 --- a/website/docs/r/workspaces_connection_alias.html.markdown +++ b/website/docs/r/workspaces_connection_alias.html.markdown @@ -27,7 +27,7 @@ The following arguments are required: * `connection_string` - (Required) The connection string specified for the connection alias. The connection string must be in the form of a fully qualified domain name (FQDN), such as www.example.com. * `tags` – (Optional) A map of tags assigned to the WorkSpaces Connection Alias. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. -## Attributes Reference +## Attribute Reference In addition to all arguments above, the following attributes are exported: From e3dccac78b31f41e301d6a4fb88eb879dabad40f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jul 2023 11:39:35 -0400 Subject: [PATCH 19/19] Fix tfproviderdocs errors. --- website/docs/r/workspaces_connection_alias.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/workspaces_connection_alias.html.markdown b/website/docs/r/workspaces_connection_alias.html.markdown index 15d47b0e53c8..54a936eba428 100644 --- a/website/docs/r/workspaces_connection_alias.html.markdown +++ b/website/docs/r/workspaces_connection_alias.html.markdown @@ -29,7 +29,7 @@ The following arguments are required: ## Attribute Reference -In addition to all arguments above, the following attributes are exported: +This resource exports the following attributes in addition to the arguments above: * `id` - The identifier of the connection alias. * `owner_account_id` - The identifier of the Amazon Web Services account that owns the connection alias. @@ -46,7 +46,7 @@ In addition to all arguments above, the following attributes are exported: ## Import -WorkSpaces Connection Alias can be imported using the `id`, e.g., +Import WorkSpaces Connection Alias using the connection alias ID. For example: ``` $ terraform import aws_workspaces_connection_alias.example rft-8012925589