From fbabd98d1052a0913d9ed367425cbd1f753228a0 Mon Sep 17 00:00:00 2001 From: Frank van Boven Date: Fri, 8 Mar 2024 15:36:12 +0100 Subject: [PATCH 01/15] New Resource --- .../servicecatalogappregistry/application.go | 240 ++++++++++++++++++ .../application_test.go | 183 +++++++++++++ .../servicecatalogappregistry/exports_test.go | 10 + .../service_package_gen.go | 7 +- ...talogappregistry_application.html.markdown | 69 +++++ 5 files changed, 508 insertions(+), 1 deletion(-) create mode 100644 internal/service/servicecatalogappregistry/application.go create mode 100644 internal/service/servicecatalogappregistry/application_test.go create mode 100644 internal/service/servicecatalogappregistry/exports_test.go create mode 100644 website/docs/r/servicecatalogappregistry_application.html.markdown diff --git a/internal/service/servicecatalogappregistry/application.go b/internal/service/servicecatalogappregistry/application.go new file mode 100644 index 00000000000..6760be75ac6 --- /dev/null +++ b/internal/service/servicecatalogappregistry/application.go @@ -0,0 +1,240 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package servicecatalogappregistry + +import ( + "context" + "errors" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry" + awstypes "github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry/types" + "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/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/errs" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// Function annotations are used for resource registration to the Provider. DO NOT EDIT. +// @FrameworkResource(name="Application") +func newResourceApplication(_ context.Context) (resource.ResourceWithConfigure, error) { + r := &resourceApplication{} + + return r, nil +} + +const ( + ResNameApplication = "Application" +) + +type resourceApplication struct { + framework.ResourceWithConfigure +} + +func (r *resourceApplication) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "aws_servicecatalog_application" +} + +func (r *resourceApplication) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "arn": framework.ARNAttributeComputedOnly(), + "description": schema.StringAttribute{ + Optional: true, + }, + "id": framework.IDAttribute(), + "name": schema.StringAttribute{ + Required: true, + }, + }, + } +} + +func (r *resourceApplication) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + conn := r.Meta().ServiceCatalogAppRegistryClient(ctx) + + var plan resourceApplicationData + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + in := &servicecatalogappregistry.CreateApplicationInput{ + Name: aws.String(plan.Name.ValueString()), + } + + if !plan.Description.IsNull() { + in.Description = aws.String(plan.Description.ValueString()) + } + + out, err := conn.CreateApplication(ctx, in) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ServiceCatalogAppRegistry, create.ErrActionCreating, ResNameApplication, plan.Name.String(), err), + err.Error(), + ) + return + } + if out == nil || out.Application == nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ServiceCatalogAppRegistry, create.ErrActionCreating, ResNameApplication, plan.Name.String(), nil), + errors.New("empty output").Error(), + ) + return + } + + plan.ARN = flex.StringToFramework(ctx, out.Application.Arn) + plan.ID = flex.StringToFramework(ctx, out.Application.Id) + + resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) +} + +func (r *resourceApplication) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + conn := r.Meta().ServiceCatalogAppRegistryClient(ctx) + + var state resourceApplicationData + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + out, err := findApplicationByID(ctx, conn, state.ID.ValueString()) + if tfresource.NotFound(err) { + resp.State.RemoveResource(ctx) + return + } + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ServiceCatalogAppRegistry, create.ErrActionSetting, ResNameApplication, state.ID.String(), err), + err.Error(), + ) + return + } + + state.ARN = flex.StringToFramework(ctx, out.Arn) + state.ID = flex.StringToFramework(ctx, out.Id) + state.Name = flex.StringToFramework(ctx, out.Name) + state.Description = flex.StringToFramework(ctx, out.Description) + + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (r *resourceApplication) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + conn := r.Meta().ServiceCatalogAppRegistryClient(ctx) + + var plan, state resourceApplicationData + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + if !plan.Name.Equal(state.Name) || + !plan.Description.Equal(state.Description) { + + in := &servicecatalogappregistry.UpdateApplicationInput{ + Application: aws.String(plan.ID.ValueString()), + } + + if !plan.Description.IsNull() { + in.Description = aws.String(plan.Description.ValueString()) + } + + out, err := conn.UpdateApplication(ctx, in) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ServiceCatalogAppRegistry, create.ErrActionUpdating, ResNameApplication, plan.ID.String(), err), + err.Error(), + ) + return + } + if out == nil || out.Application == nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ServiceCatalogAppRegistry, create.ErrActionUpdating, ResNameApplication, plan.ID.String(), nil), + errors.New("empty output").Error(), + ) + return + } + + plan.ARN = flex.StringToFramework(ctx, out.Application.Arn) + plan.ID = flex.StringToFramework(ctx, out.Application.Id) + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) +} + +func (r *resourceApplication) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + conn := r.Meta().ServiceCatalogAppRegistryClient(ctx) + + var state resourceApplicationData + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + in := &servicecatalogappregistry.DeleteApplicationInput{ + Application: aws.String(state.ID.ValueString()), + } + + _, err := conn.DeleteApplication(ctx, in) + if err != nil { + if errs.IsA[*awstypes.ResourceNotFoundException](err) { + return + } + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ServiceCatalogAppRegistry, create.ErrActionDeleting, ResNameApplication, state.ID.String(), err), + err.Error(), + ) + return + } +} + +func (r *resourceApplication) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} + +const ( + statusChangePending = "Pending" + statusDeleting = "Deleting" + statusNormal = "Normal" + statusUpdated = "Updated" +) + +func findApplicationByID(ctx context.Context, conn *servicecatalogappregistry.Client, id string) (*servicecatalogappregistry.GetApplicationOutput, error) { + in := &servicecatalogappregistry.GetApplicationInput{ + Application: aws.String(id), + } + + out, err := conn.GetApplication(ctx, in) + if err != nil { + if errs.IsA[*awstypes.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: in, + } + } + + return nil, err + } + + if out == nil || out.Id == nil { + return nil, tfresource.NewEmptyResultError(in) + } + + return out, nil +} + +type resourceApplicationData struct { + ARN types.String `tfsdk:"arn"` + Description types.String `tfsdk:"description"` + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` +} diff --git a/internal/service/servicecatalogappregistry/application_test.go b/internal/service/servicecatalogappregistry/application_test.go new file mode 100644 index 00000000000..c5ac157d08d --- /dev/null +++ b/internal/service/servicecatalogappregistry/application_test.go @@ -0,0 +1,183 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package servicecatalogappregistry_test + +// **PLEASE DELETE THIS AND ALL TIP COMMENTS BEFORE SUBMITTING A PR FOR REVIEW!** +// +// TIP: ==== INTRODUCTION ==== +// Thank you for trying the skaff tool! +// +// You have opted to include these helpful comments. They all include "TIP:" +// to help you find and remove them when you're done with them. +// +// While some aspects of this file are customized to your input, the +// scaffold tool does *not* look at the AWS API and ensure it has correct +// function, structure, and variable names. It makes guesses based on +// commonalities. You will need to make significant adjustments. +// +// In other words, as generated, this is a rough outline of the work you will +// need to do. If something doesn't make sense for your situation, get rid of +// it. + +import ( + // TIP: ==== IMPORTS ==== + // This is a common set of imports but not customized to your code since + // your code hasn't been written yet. Make sure you, your IDE, or + // goimports -w fixes these imports. + // + // The provider linter wants your imports to be in two groups: first, + // standard library (i.e., "fmt" or "strings"), second, everything else. + // + // Also, AWS Go SDK v2 may handle nested structures differently than v1, + // using the services/servicecatalogappregistry/types package. If so, you'll + // need to import types and reference the nested types, e.g., as + // types.. + "context" + "errors" + "fmt" + "testing" + + "github.com/YakDriver/regexache" + "github.com/aws/aws-sdk-go-v2/aws" + servicecatalogappregistry_sdkv2 "github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry" + "github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry/types" + 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" + "github.com/hashicorp/terraform-provider-aws/internal/errs" + servicecatalogappregistry "github.com/hashicorp/terraform-provider-aws/internal/service/servicecatalogappregistry" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// TIP: ==== ACCEPTANCE TESTS ==== +// This is an example of a basic acceptance test. This should test as much of +// standard functionality of the resource as possible, and test importing, if +// applicable. We prefix its name with "TestAcc", the service, and the +// resource name. +// +// Acceptance test access AWS and cost money to run. +func TestAccServiceCatalogAppRegistryApplication_basic(t *testing.T) { + ctx := acctest.Context(t) + // TIP: This is a long-running test guard for tests that run longer than + // 300s (5 min) generally. + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_servicecatalog_application.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ServiceCatalogAppRegistryServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckApplicationDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccApplicationConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckApplicationExists(ctx, resourceName), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "servicecatalog", regexache.MustCompile(`/applications/+.`)), + resource.TestCheckResourceAttr(resourceName, "name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccServiceCatalogAppRegistryApplication_disappears(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_servicecatalog_application.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ServiceCatalogAppRegistryServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckApplicationDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccApplicationConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckApplicationExists(ctx, resourceName), + acctest.CheckFrameworkResourceDisappears(ctx, acctest.Provider, servicecatalogappregistry.ResourceApplication, resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckApplicationDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).ServiceCatalogAppRegistryClient(ctx) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_servicecatalog_application" { + continue + } + + _, err := conn.GetApplication(ctx, &servicecatalogappregistry_sdkv2.GetApplicationInput{ + Application: aws.String(rs.Primary.Attributes["name"]), + }) + + if errs.IsA[*types.ResourceNotFoundException](err) { + return nil + } + if err != nil { + return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingDestroyed, servicecatalogappregistry.ResNameApplication, rs.Primary.ID, err) + } + + return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingDestroyed, servicecatalogappregistry.ResNameApplication, rs.Primary.ID, errors.New("not destroyed")) + } + + return nil + } +} + +func testAccCheckApplicationExists(ctx context.Context, name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingExistence, servicecatalogappregistry.ResNameApplication, name, errors.New("not found")) + } + + if rs.Primary.ID == "" { + return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingExistence, servicecatalogappregistry.ResNameApplication, name, errors.New("not set")) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).ServiceCatalogAppRegistryClient(ctx) + + _, err := servicecatalogappregistry.FindApplicationByID(ctx, conn, rs.Primary.ID) + if err != nil { + return err + } + + return nil + } +} + +func testAccApplicationConfig_basic(name string) string { + return fmt.Sprintf(` +resource "aws_servicecatalog_application" "test" { + name = %[1]q +} +`, name) +} diff --git a/internal/service/servicecatalogappregistry/exports_test.go b/internal/service/servicecatalogappregistry/exports_test.go new file mode 100644 index 00000000000..2ab5f51cc2f --- /dev/null +++ b/internal/service/servicecatalogappregistry/exports_test.go @@ -0,0 +1,10 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package servicecatalogappregistry + +// Exports for use in tests only. +var ( + FindApplicationByID = findApplicationByID + ResourceApplication = newResourceApplication +) diff --git a/internal/service/servicecatalogappregistry/service_package_gen.go b/internal/service/servicecatalogappregistry/service_package_gen.go index dbbec78ea9e..b22b53b162e 100644 --- a/internal/service/servicecatalogappregistry/service_package_gen.go +++ b/internal/service/servicecatalogappregistry/service_package_gen.go @@ -19,7 +19,12 @@ 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: newResourceApplication, + Name: "Application", + }, + } } func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePackageSDKDataSource { diff --git a/website/docs/r/servicecatalogappregistry_application.html.markdown b/website/docs/r/servicecatalogappregistry_application.html.markdown new file mode 100644 index 00000000000..4fcfac2f5e1 --- /dev/null +++ b/website/docs/r/servicecatalogappregistry_application.html.markdown @@ -0,0 +1,69 @@ +--- +subcategory: "Service Catalog AppRegistry" +layout: "aws" +page_title: "AWS: aws_servicecatalogappregistry_application" +description: |- + Terraform resource for managing an AWS Service Catalog AppRegistry Application. +--- +` +# Resource: aws_servicecatalogappregistry_application + +Terraform resource for managing an AWS Service Catalog AppRegistry Application. + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_servicecatalogappregistry_application" "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. + +## Attribute Reference + +This resource exports the following attributes in addition to the arguments above: + +* `arn` - ARN of the Application. 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 + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import Service Catalog AppRegistry Application using the `example_id_arg`. For example: + +```terraform +import { + to = aws_servicecatalogappregistry_application.example + id = "application-id-12345678" +} +``` + +Using `terraform import`, import Service Catalog AppRegistry Application using the `example_id_arg`. For example: + +```console +% terraform import aws_servicecatalogappregistry_application.example application-id-12345678 +``` From a742cc1a726c954eff95f74d1e83aca7e8339f27 Mon Sep 17 00:00:00 2001 From: Frank van Boven Date: Fri, 8 Mar 2024 17:04:38 +0100 Subject: [PATCH 02/15] Add initial documentation --- .../servicecatalogappregistry/application.go | 2 +- .../application_test.go | 46 ++-------------- ...talogappregistry_application.html.markdown | 52 ++++++++++--------- 3 files changed, 33 insertions(+), 67 deletions(-) diff --git a/internal/service/servicecatalogappregistry/application.go b/internal/service/servicecatalogappregistry/application.go index 6760be75ac6..addbee9cbc0 100644 --- a/internal/service/servicecatalogappregistry/application.go +++ b/internal/service/servicecatalogappregistry/application.go @@ -40,7 +40,7 @@ type resourceApplication struct { } func (r *resourceApplication) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = "aws_servicecatalog_application" + resp.TypeName = "aws_servicecatalogappregistry_application" } func (r *resourceApplication) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { diff --git a/internal/service/servicecatalogappregistry/application_test.go b/internal/service/servicecatalogappregistry/application_test.go index c5ac157d08d..11cd2458c0b 100644 --- a/internal/service/servicecatalogappregistry/application_test.go +++ b/internal/service/servicecatalogappregistry/application_test.go @@ -3,36 +3,7 @@ package servicecatalogappregistry_test -// **PLEASE DELETE THIS AND ALL TIP COMMENTS BEFORE SUBMITTING A PR FOR REVIEW!** -// -// TIP: ==== INTRODUCTION ==== -// Thank you for trying the skaff tool! -// -// You have opted to include these helpful comments. They all include "TIP:" -// to help you find and remove them when you're done with them. -// -// While some aspects of this file are customized to your input, the -// scaffold tool does *not* look at the AWS API and ensure it has correct -// function, structure, and variable names. It makes guesses based on -// commonalities. You will need to make significant adjustments. -// -// In other words, as generated, this is a rough outline of the work you will -// need to do. If something doesn't make sense for your situation, get rid of -// it. - import ( - // TIP: ==== IMPORTS ==== - // This is a common set of imports but not customized to your code since - // your code hasn't been written yet. Make sure you, your IDE, or - // goimports -w fixes these imports. - // - // The provider linter wants your imports to be in two groups: first, - // standard library (i.e., "fmt" or "strings"), second, everything else. - // - // Also, AWS Go SDK v2 may handle nested structures differently than v1, - // using the services/servicecatalogappregistry/types package. If so, you'll - // need to import types and reference the nested types, e.g., as - // types.. "context" "errors" "fmt" @@ -53,23 +24,14 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// TIP: ==== ACCEPTANCE TESTS ==== -// This is an example of a basic acceptance test. This should test as much of -// standard functionality of the resource as possible, and test importing, if -// applicable. We prefix its name with "TestAcc", the service, and the -// resource name. -// -// Acceptance test access AWS and cost money to run. func TestAccServiceCatalogAppRegistryApplication_basic(t *testing.T) { ctx := acctest.Context(t) - // TIP: This is a long-running test guard for tests that run longer than - // 300s (5 min) generally. if testing.Short() { t.Skip("skipping long-running test in short mode") } rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_servicecatalog_application.test" + resourceName := "aws_servicecatalogappregistry_application.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { @@ -103,7 +65,7 @@ func TestAccServiceCatalogAppRegistryApplication_disappears(t *testing.T) { } rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_servicecatalog_application.test" + resourceName := "aws_servicecatalogappregistry_application.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { @@ -130,7 +92,7 @@ func testAccCheckApplicationDestroy(ctx context.Context) resource.TestCheckFunc conn := acctest.Provider.Meta().(*conns.AWSClient).ServiceCatalogAppRegistryClient(ctx) for _, rs := range s.RootModule().Resources { - if rs.Type != "aws_servicecatalog_application" { + if rs.Type != "aws_servicecatalogappregistry_application" { continue } @@ -176,7 +138,7 @@ func testAccCheckApplicationExists(ctx context.Context, name string) resource.Te func testAccApplicationConfig_basic(name string) string { return fmt.Sprintf(` -resource "aws_servicecatalog_application" "test" { +resource "aws_servicecatalogappregistry_application" "test" { name = %[1]q } `, name) diff --git a/website/docs/r/servicecatalogappregistry_application.html.markdown b/website/docs/r/servicecatalogappregistry_application.html.markdown index 4fcfac2f5e1..d634fdd3238 100644 --- a/website/docs/r/servicecatalogappregistry_application.html.markdown +++ b/website/docs/r/servicecatalogappregistry_application.html.markdown @@ -1,21 +1,15 @@ --- -subcategory: "Service Catalog AppRegistry" +subcategory: "Service Catalog" layout: "aws" page_title: "AWS: aws_servicecatalogappregistry_application" description: |- Terraform resource for managing an AWS Service Catalog AppRegistry Application. --- -` # Resource: aws_servicecatalogappregistry_application -Terraform resource for managing an AWS Service Catalog AppRegistry Application. +Terraform resource for managing an AWS Service Catalog AppRegistry Application. + +~> **NOTE: ** An AWS Service Catalog AppRegistry Application is also available in the AWS Console as "MyApplications" ## Example Usage @@ -23,37 +17,47 @@ Terraform resource for managing an AWS Service Catalog AppRegistry Application. ```terraform resource "aws_servicecatalogappregistry_application" "example" { + name = "myApplication" +} +``` + +### Connecting resources + +```terraform +resource "aws_servicecatalogappregistry_application" "example" { + name = "myApplication" } + +resource "aws_s3_bucket" "bucket" { + bucket = "application_bucket" + + tags = { + awsApplication = aws_servicecatalogappregistry_application.example.arn + } +} + ``` ## 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. +* `Name` - (Required) Name of the application. The name must be unique in the region in which you are creating the application. 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. +* `description` - (Optional) Description of the application. ## Attribute Reference This resource exports the following attributes in addition to the arguments above: -* `arn` - ARN of the Application. 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`) +* `arn` - ARN of the Application. +* `id` - Identifier of the Application ## Import -In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import Service Catalog AppRegistry Application using the `example_id_arg`. For example: +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import Service Catalog AppRegistry Application using the `id`. For example: ```terraform import { @@ -62,7 +66,7 @@ import { } ``` -Using `terraform import`, import Service Catalog AppRegistry Application using the `example_id_arg`. For example: +Using `terraform import`, import AWS Service Catalog AppRegistry Application using the `id`. For example: ```console % terraform import aws_servicecatalogappregistry_application.example application-id-12345678 From 594f582cdb3072bfcea07559f593dc81a3e2b7ce Mon Sep 17 00:00:00 2001 From: Frank van Boven Date: Fri, 8 Mar 2024 19:04:00 +0100 Subject: [PATCH 03/15] Add Changelog --- .changelog/36277.txt | 3 +++ .../docs/r/servicecatalogappregistry_application.html.markdown | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .changelog/36277.txt diff --git a/.changelog/36277.txt b/.changelog/36277.txt new file mode 100644 index 00000000000..be771f81971 --- /dev/null +++ b/.changelog/36277.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_servicecatalogappregistry_application +``` diff --git a/website/docs/r/servicecatalogappregistry_application.html.markdown b/website/docs/r/servicecatalogappregistry_application.html.markdown index d634fdd3238..e6c019e1898 100644 --- a/website/docs/r/servicecatalogappregistry_application.html.markdown +++ b/website/docs/r/servicecatalogappregistry_application.html.markdown @@ -52,7 +52,7 @@ The following arguments are optional: This resource exports the following attributes in addition to the arguments above: -* `arn` - ARN of the Application. +* `arn` - ARN of the Application. * `id` - Identifier of the Application ## Import From 3374025c50f95635e748847b38ddc520d1bdcf47 Mon Sep 17 00:00:00 2001 From: Frank van Boven Date: Fri, 8 Mar 2024 19:12:48 +0100 Subject: [PATCH 04/15] PR feedback tweaks --- internal/service/servicecatalogappregistry/application.go | 8 -------- .../service/servicecatalogappregistry/application_test.go | 5 +---- .../r/servicecatalogappregistry_application.html.markdown | 6 +++--- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/internal/service/servicecatalogappregistry/application.go b/internal/service/servicecatalogappregistry/application.go index addbee9cbc0..f68240cea4b 100644 --- a/internal/service/servicecatalogappregistry/application.go +++ b/internal/service/servicecatalogappregistry/application.go @@ -139,7 +139,6 @@ func (r *resourceApplication) Update(ctx context.Context, req resource.UpdateReq if !plan.Name.Equal(state.Name) || !plan.Description.Equal(state.Description) { - in := &servicecatalogappregistry.UpdateApplicationInput{ Application: aws.String(plan.ID.ValueString()), } @@ -201,13 +200,6 @@ func (r *resourceApplication) ImportState(ctx context.Context, req resource.Impo resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) } -const ( - statusChangePending = "Pending" - statusDeleting = "Deleting" - statusNormal = "Normal" - statusUpdated = "Updated" -) - func findApplicationByID(ctx context.Context, conn *servicecatalogappregistry.Client, id string) (*servicecatalogappregistry.GetApplicationOutput, error) { in := &servicecatalogappregistry.GetApplicationInput{ Application: aws.String(id), diff --git a/internal/service/servicecatalogappregistry/application_test.go b/internal/service/servicecatalogappregistry/application_test.go index 11cd2458c0b..4e48909c4ba 100644 --- a/internal/service/servicecatalogappregistry/application_test.go +++ b/internal/service/servicecatalogappregistry/application_test.go @@ -128,11 +128,8 @@ func testAccCheckApplicationExists(ctx context.Context, name string) resource.Te conn := acctest.Provider.Meta().(*conns.AWSClient).ServiceCatalogAppRegistryClient(ctx) _, err := servicecatalogappregistry.FindApplicationByID(ctx, conn, rs.Primary.ID) - if err != nil { - return err - } - return nil + return err } } diff --git a/website/docs/r/servicecatalogappregistry_application.html.markdown b/website/docs/r/servicecatalogappregistry_application.html.markdown index e6c019e1898..5a336723445 100644 --- a/website/docs/r/servicecatalogappregistry_application.html.markdown +++ b/website/docs/r/servicecatalogappregistry_application.html.markdown @@ -1,5 +1,5 @@ --- -subcategory: "Service Catalog" +subcategory: "Service Catalog AppRegistry" layout: "aws" page_title: "AWS: aws_servicecatalogappregistry_application" description: |- @@ -7,9 +7,9 @@ description: |- --- # Resource: aws_servicecatalogappregistry_application -Terraform resource for managing an AWS Service Catalog AppRegistry Application. +Terraform resource for managing an AWS Service Catalog AppRegistry Application. -~> **NOTE: ** An AWS Service Catalog AppRegistry Application is also available in the AWS Console as "MyApplications" +~> **NOTE:** An AWS Service Catalog AppRegistry Application is also available in the AWS Console as "MyApplications" ## Example Usage From 6804e63f80b64e1e63939f9b3aa01c3e9c692885 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 11:33:51 -0400 Subject: [PATCH 05/15] r/aws_servicecatalogappregistry_application(test): tidy imports --- .../application_test.go | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/internal/service/servicecatalogappregistry/application_test.go b/internal/service/servicecatalogappregistry/application_test.go index 4e48909c4ba..4f23609add3 100644 --- a/internal/service/servicecatalogappregistry/application_test.go +++ b/internal/service/servicecatalogappregistry/application_test.go @@ -11,7 +11,7 @@ import ( "github.com/YakDriver/regexache" "github.com/aws/aws-sdk-go-v2/aws" - servicecatalogappregistry_sdkv2 "github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry" + "github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry" "github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" @@ -20,16 +20,12 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/errs" - servicecatalogappregistry "github.com/hashicorp/terraform-provider-aws/internal/service/servicecatalogappregistry" + tfservicecatalogappregistry "github.com/hashicorp/terraform-provider-aws/internal/service/servicecatalogappregistry" "github.com/hashicorp/terraform-provider-aws/names" ) func TestAccServiceCatalogAppRegistryApplication_basic(t *testing.T) { ctx := acctest.Context(t) - if testing.Short() { - t.Skip("skipping long-running test in short mode") - } - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_servicecatalogappregistry_application.test" @@ -60,10 +56,6 @@ func TestAccServiceCatalogAppRegistryApplication_basic(t *testing.T) { func TestAccServiceCatalogAppRegistryApplication_disappears(t *testing.T) { ctx := acctest.Context(t) - if testing.Short() { - t.Skip("skipping long-running test in short mode") - } - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_servicecatalogappregistry_application.test" @@ -79,7 +71,7 @@ func TestAccServiceCatalogAppRegistryApplication_disappears(t *testing.T) { Config: testAccApplicationConfig_basic(rName), Check: resource.ComposeTestCheckFunc( testAccCheckApplicationExists(ctx, resourceName), - acctest.CheckFrameworkResourceDisappears(ctx, acctest.Provider, servicecatalogappregistry.ResourceApplication, resourceName), + acctest.CheckFrameworkResourceDisappears(ctx, acctest.Provider, tfservicecatalogappregistry.ResourceApplication, resourceName), ), ExpectNonEmptyPlan: true, }, @@ -96,7 +88,7 @@ func testAccCheckApplicationDestroy(ctx context.Context) resource.TestCheckFunc continue } - _, err := conn.GetApplication(ctx, &servicecatalogappregistry_sdkv2.GetApplicationInput{ + _, err := conn.GetApplication(ctx, &servicecatalogappregistry.GetApplicationInput{ Application: aws.String(rs.Primary.Attributes["name"]), }) @@ -104,10 +96,10 @@ func testAccCheckApplicationDestroy(ctx context.Context) resource.TestCheckFunc return nil } if err != nil { - return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingDestroyed, servicecatalogappregistry.ResNameApplication, rs.Primary.ID, err) + return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingDestroyed, tfservicecatalogappregistry.ResNameApplication, rs.Primary.ID, err) } - return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingDestroyed, servicecatalogappregistry.ResNameApplication, rs.Primary.ID, errors.New("not destroyed")) + return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingDestroyed, tfservicecatalogappregistry.ResNameApplication, rs.Primary.ID, errors.New("not destroyed")) } return nil @@ -118,16 +110,16 @@ func testAccCheckApplicationExists(ctx context.Context, name string) resource.Te return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] if !ok { - return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingExistence, servicecatalogappregistry.ResNameApplication, name, errors.New("not found")) + return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingExistence, tfservicecatalogappregistry.ResNameApplication, name, errors.New("not found")) } if rs.Primary.ID == "" { - return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingExistence, servicecatalogappregistry.ResNameApplication, name, errors.New("not set")) + return create.Error(names.ServiceCatalogAppRegistry, create.ErrActionCheckingExistence, tfservicecatalogappregistry.ResNameApplication, name, errors.New("not set")) } conn := acctest.Provider.Meta().(*conns.AWSClient).ServiceCatalogAppRegistryClient(ctx) - _, err := servicecatalogappregistry.FindApplicationByID(ctx, conn, rs.Primary.ID) + _, err := tfservicecatalogappregistry.FindApplicationByID(ctx, conn, rs.Primary.ID) return err } From 1692f790078290af3c6b12da759418f1cad6c4fb Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 13:27:27 -0400 Subject: [PATCH 06/15] names: add service catalog app registry endpoint id --- names/names.go | 1 + 1 file changed, 1 insertion(+) diff --git a/names/names.go b/names/names.go index 4868b815590..0069c3c9000 100644 --- a/names/names.go +++ b/names/names.go @@ -66,6 +66,7 @@ const ( Route53DomainsEndpointID = "route53domains" SchedulerEndpointID = "scheduler" ServiceQuotasEndpointID = "servicequotas" + ServiceCatalogAppRegistryEndpointID = "servicecatalog-appregistry" ShieldEndpointID = "shield" SSMEndpointID = "ssm" SSMIncidentsEndpointID = "ssm-incidents" From 7dd699aee9fbeb270a38bab58620aded40e2dbb0 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 13:27:48 -0400 Subject: [PATCH 07/15] r/aws_servicecatalogappregistry_application(test): add pre-checks --- internal/service/servicecatalogappregistry/application_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/service/servicecatalogappregistry/application_test.go b/internal/service/servicecatalogappregistry/application_test.go index 4f23609add3..103b25a6d7a 100644 --- a/internal/service/servicecatalogappregistry/application_test.go +++ b/internal/service/servicecatalogappregistry/application_test.go @@ -32,6 +32,7 @@ func TestAccServiceCatalogAppRegistryApplication_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.ServiceCatalogAppRegistryEndpointID) }, ErrorCheck: acctest.ErrorCheck(t, names.ServiceCatalogAppRegistryServiceID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, @@ -62,6 +63,7 @@ func TestAccServiceCatalogAppRegistryApplication_disappears(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.ServiceCatalogAppRegistryEndpointID) }, ErrorCheck: acctest.ErrorCheck(t, names.ServiceCatalogAppRegistryServiceID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, From b66561139a0c59838ad323e82c38ce37d1159e72 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 13:35:28 -0400 Subject: [PATCH 08/15] r/aws_servicecatalogappregistry_application(test): prefer finder in test checks --- .../service/servicecatalogappregistry/application_test.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/internal/service/servicecatalogappregistry/application_test.go b/internal/service/servicecatalogappregistry/application_test.go index 103b25a6d7a..2b02aba9356 100644 --- a/internal/service/servicecatalogappregistry/application_test.go +++ b/internal/service/servicecatalogappregistry/application_test.go @@ -10,8 +10,6 @@ import ( "testing" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry" "github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" @@ -90,10 +88,7 @@ func testAccCheckApplicationDestroy(ctx context.Context) resource.TestCheckFunc continue } - _, err := conn.GetApplication(ctx, &servicecatalogappregistry.GetApplicationInput{ - Application: aws.String(rs.Primary.Attributes["name"]), - }) - + _, err := tfservicecatalogappregistry.FindApplicationByID(ctx, conn, rs.Primary.ID) if errs.IsA[*types.ResourceNotFoundException](err) { return nil } From 8f03f5f6aefb512d8bef5a1868087bce3c92b0ab Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 13:40:22 -0400 Subject: [PATCH 09/15] r/aws_servicecatalogappregistry_application(doc): tidy descriptions --- .../r/servicecatalogappregistry_application.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/r/servicecatalogappregistry_application.html.markdown b/website/docs/r/servicecatalogappregistry_application.html.markdown index 5a336723445..84dc2a0356d 100644 --- a/website/docs/r/servicecatalogappregistry_application.html.markdown +++ b/website/docs/r/servicecatalogappregistry_application.html.markdown @@ -9,7 +9,7 @@ description: |- Terraform resource for managing an AWS Service Catalog AppRegistry Application. -~> **NOTE:** An AWS Service Catalog AppRegistry Application is also available in the AWS Console as "MyApplications" +~> An AWS Service Catalog AppRegistry Application is displayed in the AWS Console under "MyApplications". ## Example Usage @@ -42,7 +42,7 @@ resource "aws_s3_bucket" "bucket" { The following arguments are required: -* `Name` - (Required) Name of the application. The name must be unique in the region in which you are creating the application. +* `name` - (Required) Name of the application. The name must be unique within an AWS region. The following arguments are optional: @@ -52,8 +52,8 @@ The following arguments are optional: This resource exports the following attributes in addition to the arguments above: -* `arn` - ARN of the Application. -* `id` - Identifier of the Application +* `arn` - ARN (Amazon Resource Name) of the application. +* `id` - Identifier of the application. ## Import From 9dada6bc05286d395e140075dd10aab71617030a Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 13:42:59 -0400 Subject: [PATCH 10/15] r/aws_servicecatalogappregistry_application(doc): switch example names To avoid any confusion with the heading in the AWS console. --- .../r/servicecatalogappregistry_application.html.markdown | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/website/docs/r/servicecatalogappregistry_application.html.markdown b/website/docs/r/servicecatalogappregistry_application.html.markdown index 84dc2a0356d..5e93f4d505f 100644 --- a/website/docs/r/servicecatalogappregistry_application.html.markdown +++ b/website/docs/r/servicecatalogappregistry_application.html.markdown @@ -17,7 +17,7 @@ Terraform resource for managing an AWS Service Catalog AppRegistry Application. ```terraform resource "aws_servicecatalogappregistry_application" "example" { - name = "myApplication" + name = "example-app" } ``` @@ -25,17 +25,16 @@ resource "aws_servicecatalogappregistry_application" "example" { ```terraform resource "aws_servicecatalogappregistry_application" "example" { - name = "myApplication" + name = "example-app" } resource "aws_s3_bucket" "bucket" { - bucket = "application_bucket" + bucket = "example-bucket" tags = { awsApplication = aws_servicecatalogappregistry_application.example.arn } } - ``` ## Argument Reference From 81137b220c0cfc68a8a1d9f89a2e838bfde6524c Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 13:52:11 -0400 Subject: [PATCH 11/15] r/aws_servicecatalogappregistry_application: switch to autoflex --- .../servicecatalogappregistry/application.go | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/internal/service/servicecatalogappregistry/application.go b/internal/service/servicecatalogappregistry/application.go index f68240cea4b..8170b4c201f 100644 --- a/internal/service/servicecatalogappregistry/application.go +++ b/internal/service/servicecatalogappregistry/application.go @@ -23,12 +23,9 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// Function annotations are used for resource registration to the Provider. DO NOT EDIT. // @FrameworkResource(name="Application") func newResourceApplication(_ context.Context) (resource.ResourceWithConfigure, error) { - r := &resourceApplication{} - - return r, nil + return &resourceApplication{}, nil } const ( @@ -67,12 +64,10 @@ func (r *resourceApplication) Create(ctx context.Context, req resource.CreateReq return } - in := &servicecatalogappregistry.CreateApplicationInput{ - Name: aws.String(plan.Name.ValueString()), - } - - if !plan.Description.IsNull() { - in.Description = aws.String(plan.Description.ValueString()) + in := &servicecatalogappregistry.CreateApplicationInput{} + resp.Diagnostics.Append(flex.Expand(ctx, plan, in)...) + if resp.Diagnostics.HasError() { + return } out, err := conn.CreateApplication(ctx, in) @@ -91,9 +86,7 @@ func (r *resourceApplication) Create(ctx context.Context, req resource.CreateReq return } - plan.ARN = flex.StringToFramework(ctx, out.Application.Arn) - plan.ID = flex.StringToFramework(ctx, out.Application.Id) - + resp.Diagnostics.Append(flex.Flatten(ctx, out.Application, &plan)...) resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) } @@ -119,11 +112,7 @@ func (r *resourceApplication) Read(ctx context.Context, req resource.ReadRequest return } - state.ARN = flex.StringToFramework(ctx, out.Arn) - state.ID = flex.StringToFramework(ctx, out.Id) - state.Name = flex.StringToFramework(ctx, out.Name) - state.Description = flex.StringToFramework(ctx, out.Description) - + resp.Diagnostics.Append(flex.Flatten(ctx, out, &state)...) resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) } @@ -163,8 +152,7 @@ func (r *resourceApplication) Update(ctx context.Context, req resource.UpdateReq return } - plan.ARN = flex.StringToFramework(ctx, out.Application.Arn) - plan.ID = flex.StringToFramework(ctx, out.Application.Id) + resp.Diagnostics.Append(flex.Flatten(ctx, out.Application, &plan)...) } resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) From e5a9150e7fe6e0b8e8f7bbbb0f2d96224895f010 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 14:09:45 -0400 Subject: [PATCH 12/15] r/aws_servicecatalogappregistry_application: name update forces new resource AWS has deprecated the ability to updated application names in-place and attempting to do so will return a ValidationException. --- .../servicecatalogappregistry/application.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/internal/service/servicecatalogappregistry/application.go b/internal/service/servicecatalogappregistry/application.go index 8170b4c201f..3402175aac0 100644 --- a/internal/service/servicecatalogappregistry/application.go +++ b/internal/service/servicecatalogappregistry/application.go @@ -13,6 +13,8 @@ import ( "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" @@ -50,6 +52,12 @@ func (r *resourceApplication) Schema(ctx context.Context, req resource.SchemaReq "id": framework.IDAttribute(), "name": schema.StringAttribute{ Required: true, + // Name cannot be updated despite being present in the update API struct. + // + // ValidationException: Application name update feature has been deprecated. + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, }, }, } @@ -128,13 +136,13 @@ func (r *resourceApplication) Update(ctx context.Context, req resource.UpdateReq if !plan.Name.Equal(state.Name) || !plan.Description.Equal(state.Description) { - in := &servicecatalogappregistry.UpdateApplicationInput{ - Application: aws.String(plan.ID.ValueString()), - } - if !plan.Description.IsNull() { - in.Description = aws.String(plan.Description.ValueString()) + in := &servicecatalogappregistry.UpdateApplicationInput{} + resp.Diagnostics.Append(flex.Expand(ctx, plan, in)...) + if resp.Diagnostics.HasError() { + return } + in.Application = aws.String(plan.ID.ValueString()) // Set manually, AWS naming is inconsistent out, err := conn.UpdateApplication(ctx, in) if err != nil { From 8a21345c654982cb4ace6e886432f622b7e8ca4a Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 14:10:03 -0400 Subject: [PATCH 13/15] r/aws_servicecatalogappregistry_application(test): add update test --- .../application_test.go | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/internal/service/servicecatalogappregistry/application_test.go b/internal/service/servicecatalogappregistry/application_test.go index 2b02aba9356..48cb617434d 100644 --- a/internal/service/servicecatalogappregistry/application_test.go +++ b/internal/service/servicecatalogappregistry/application_test.go @@ -79,6 +79,56 @@ func TestAccServiceCatalogAppRegistryApplication_disappears(t *testing.T) { }) } +func TestAccServiceCatalogAppRegistryApplication_update(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rNameUpdated := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + description := "text1" + descriptionUpdated := "text2" + resourceName := "aws_servicecatalogappregistry_application.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.ServiceCatalogAppRegistryEndpointID) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ServiceCatalogAppRegistryServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckApplicationDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccApplicationConfig_description(rName, description), + Check: resource.ComposeTestCheckFunc( + testAccCheckApplicationExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "description", description), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccApplicationConfig_description(rName, descriptionUpdated), + Check: resource.ComposeTestCheckFunc( + testAccCheckApplicationExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "description", descriptionUpdated), + ), + }, + { + Config: testAccApplicationConfig_description(rNameUpdated, description), + Check: resource.ComposeTestCheckFunc( + testAccCheckApplicationExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, "name", rNameUpdated), + resource.TestCheckResourceAttr(resourceName, "description", description), + ), + }, + }, + }) +} + func testAccCheckApplicationDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).ServiceCatalogAppRegistryClient(ctx) @@ -129,3 +179,12 @@ resource "aws_servicecatalogappregistry_application" "test" { } `, name) } + +func testAccApplicationConfig_description(name, description string) string { + return fmt.Sprintf(` +resource "aws_servicecatalogappregistry_application" "test" { + name = %[1]q + description = %[2]q +} +`, name, description) +} From 1f2c7460783122f38afecd5ac3e190e908bd0b3a Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 14:14:29 -0400 Subject: [PATCH 14/15] r/aws_servicecatalogappregistry_application(doc): tidy heading --- .../docs/r/servicecatalogappregistry_application.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/servicecatalogappregistry_application.html.markdown b/website/docs/r/servicecatalogappregistry_application.html.markdown index 5e93f4d505f..df10e8b647e 100644 --- a/website/docs/r/servicecatalogappregistry_application.html.markdown +++ b/website/docs/r/servicecatalogappregistry_application.html.markdown @@ -21,7 +21,7 @@ resource "aws_servicecatalogappregistry_application" "example" { } ``` -### Connecting resources +### Connecting Resources ```terraform resource "aws_servicecatalogappregistry_application" "example" { From b7cfe3c7cfa40e8c5196ab56f27881f5de72ebc3 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 26 Mar 2024 14:47:07 -0400 Subject: [PATCH 15/15] r/aws_servicecatalogappregistry_application: fix whitespace linter finding --- internal/service/servicecatalogappregistry/application.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/service/servicecatalogappregistry/application.go b/internal/service/servicecatalogappregistry/application.go index 3402175aac0..5bd8af104bb 100644 --- a/internal/service/servicecatalogappregistry/application.go +++ b/internal/service/servicecatalogappregistry/application.go @@ -134,9 +134,7 @@ func (r *resourceApplication) Update(ctx context.Context, req resource.UpdateReq return } - if !plan.Name.Equal(state.Name) || - !plan.Description.Equal(state.Description) { - + if !plan.Description.Equal(state.Description) { in := &servicecatalogappregistry.UpdateApplicationInput{} resp.Diagnostics.Append(flex.Expand(ctx, plan, in)...) if resp.Diagnostics.HasError() {