diff --git a/.changelog/39744.txt b/.changelog/39744.txt new file mode 100644 index 000000000000..707a45d89897 --- /dev/null +++ b/.changelog/39744.txt @@ -0,0 +1,7 @@ +```release-note:bug +resource/aws_resourceexplorer2_index: Correctly mark incomplete `AGGREGATOR` indexes as [tainted](https://developer.hashicorp.com/terraform/cli/state/taint#the-tainted-status) on Create +``` + +```release-note:enhancement +resource/aws_resourceexplorer2_view: Add `scope` argument +``` \ No newline at end of file diff --git a/internal/service/resourceexplorer2/exports_test.go b/internal/service/resourceexplorer2/exports_test.go index d00e26eb31bf..ebde78cba61f 100644 --- a/internal/service/resourceexplorer2/exports_test.go +++ b/internal/service/resourceexplorer2/exports_test.go @@ -5,8 +5,9 @@ package resourceexplorer2 // Exports for use in tests only. var ( + ResourceIndex = newIndexResource + ResourceView = newViewResource + FindIndex = findIndex FindViewByARN = findViewByARN - ResourceIndex = newResourceIndex - ResourceView = newResourceView ) diff --git a/internal/service/resourceexplorer2/index.go b/internal/service/resourceexplorer2/index.go index e63f7e17f326..ff89093f18d4 100644 --- a/internal/service/resourceexplorer2/index.go +++ b/internal/service/resourceexplorer2/index.go @@ -12,17 +12,18 @@ import ( "github.com/aws/aws-sdk-go-v2/service/resourceexplorer2" awstypes "github.com/aws/aws-sdk-go-v2/service/resourceexplorer2/types" "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/types" "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + sdkid "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-provider-aws/internal/enum" "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" "github.com/hashicorp/terraform-provider-aws/internal/framework" - "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" @@ -31,8 +32,9 @@ import ( // @FrameworkResource(name="Index") // @Tags(identifierAttribute="id") -func newResourceIndex(context.Context) (resource.ResourceWithConfigure, error) { - r := &resourceIndex{} +func newIndexResource(context.Context) (resource.ResourceWithConfigure, error) { + r := &indexResource{} + r.SetDefaultCreateTimeout(2 * time.Hour) r.SetDefaultUpdateTimeout(2 * time.Hour) r.SetDefaultDeleteTimeout(10 * time.Minute) @@ -40,17 +42,17 @@ func newResourceIndex(context.Context) (resource.ResourceWithConfigure, error) { return r, nil } -type resourceIndex struct { +type indexResource struct { framework.ResourceWithConfigure framework.WithImportByID framework.WithTimeouts } -func (r *resourceIndex) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { +func (*indexResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { response.TypeName = "aws_resourceexplorer2_index" } -func (r *resourceIndex) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { +func (r *indexResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { response.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ names.AttrARN: framework.ARNAttributeComputedOnly(), @@ -72,11 +74,9 @@ func (r *resourceIndex) Schema(ctx context.Context, request resource.SchemaReque } } -func (r *resourceIndex) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { +func (r *indexResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { var data indexResourceModel - response.Diagnostics.Append(request.Plan.Get(ctx, &data)...) - if response.Diagnostics.HasError() { return } @@ -84,7 +84,7 @@ func (r *resourceIndex) Create(ctx context.Context, request resource.CreateReque conn := r.Meta().ResourceExplorer2Client(ctx) input := &resourceexplorer2.CreateIndexInput{ - ClientToken: aws.String(id.UniqueId()), + ClientToken: aws.String(sdkid.UniqueId()), Tags: getTagsIn(ctx), } @@ -108,15 +108,15 @@ func (r *resourceIndex) Create(ctx context.Context, request resource.CreateReque if data.Type.ValueEnum() == awstypes.IndexTypeAggregator { input := &resourceexplorer2.UpdateIndexTypeInput{ - Arn: flex.StringFromFramework(ctx, data.ID), + Arn: fwflex.StringFromFramework(ctx, data.ID), Type: awstypes.IndexTypeAggregator, } _, err := conn.UpdateIndexType(ctx, input) if err != nil { + response.State.SetAttribute(ctx, path.Root(names.AttrID), data.ID) // Set 'id' so as to taint the resource. response.Diagnostics.AddError(fmt.Sprintf("updating Resource Explorer Index (%s)", data.ID.ValueString()), err.Error()) - return } @@ -133,11 +133,9 @@ func (r *resourceIndex) Create(ctx context.Context, request resource.CreateReque response.Diagnostics.Append(response.State.Set(ctx, &data)...) } -func (r *resourceIndex) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { +func (r *indexResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { var data indexResourceModel - response.Diagnostics.Append(request.State.Get(ctx, &data)...) - if response.Diagnostics.HasError() { return } @@ -159,7 +157,7 @@ func (r *resourceIndex) Read(ctx context.Context, request resource.ReadRequest, return } - response.Diagnostics.Append(flex.Flatten(ctx, output, &data)...) + response.Diagnostics.Append(fwflex.Flatten(ctx, output, &data)...) if response.Diagnostics.HasError() { return @@ -170,17 +168,13 @@ func (r *resourceIndex) Read(ctx context.Context, request resource.ReadRequest, response.Diagnostics.Append(response.State.Set(ctx, &data)...) } -func (r *resourceIndex) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { +func (r *indexResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { var old, new indexResourceModel - response.Diagnostics.Append(request.State.Get(ctx, &old)...) - if response.Diagnostics.HasError() { return } - response.Diagnostics.Append(request.Plan.Get(ctx, &new)...) - if response.Diagnostics.HasError() { return } @@ -189,7 +183,7 @@ func (r *resourceIndex) Update(ctx context.Context, request resource.UpdateReque conn := r.Meta().ResourceExplorer2Client(ctx) input := &resourceexplorer2.UpdateIndexTypeInput{ - Arn: flex.StringFromFramework(ctx, new.ARN), + Arn: fwflex.StringFromFramework(ctx, new.ARN), Type: new.Type.ValueEnum(), } @@ -201,8 +195,7 @@ func (r *resourceIndex) Update(ctx context.Context, request resource.UpdateReque return } - updateTimeout := r.UpdateTimeout(ctx, new.Timeouts) - if _, err := waitIndexUpdated(ctx, conn, updateTimeout); err != nil { + if _, err := waitIndexUpdated(ctx, conn, r.UpdateTimeout(ctx, new.Timeouts)); err != nil { response.Diagnostics.AddError(fmt.Sprintf("waiting for Resource Explorer Index (%s) update", new.ID.ValueString()), err.Error()) return @@ -212,11 +205,9 @@ func (r *resourceIndex) Update(ctx context.Context, request resource.UpdateReque response.Diagnostics.Append(response.State.Set(ctx, &new)...) } -func (r *resourceIndex) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { +func (r *indexResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { var data indexResourceModel - response.Diagnostics.Append(request.State.Get(ctx, &data)...) - if response.Diagnostics.HasError() { return } @@ -227,24 +218,27 @@ func (r *resourceIndex) Delete(ctx context.Context, request resource.DeleteReque names.AttrID: data.ID.ValueString(), }) _, err := conn.DeleteIndex(ctx, &resourceexplorer2.DeleteIndexInput{ - Arn: flex.StringFromFramework(ctx, data.ARN), + Arn: fwflex.StringFromFramework(ctx, data.ARN), }) + if errs.IsAErrorMessageContains[*awstypes.ValidationException](err, "The index is DELETED") { + return + } + if err != nil { response.Diagnostics.AddError(fmt.Sprintf("deleting Resource Explorer Index (%s)", data.ID.ValueString()), err.Error()) return } - deleteTimeout := r.DeleteTimeout(ctx, data.Timeouts) - if _, err := waitIndexDeleted(ctx, conn, deleteTimeout); err != nil { + if _, err := waitIndexDeleted(ctx, conn, r.DeleteTimeout(ctx, data.Timeouts)); err != nil { response.Diagnostics.AddError(fmt.Sprintf("waiting for Resource Explorer Index (%s) delete", data.ID.ValueString()), err.Error()) return } } -func (r *resourceIndex) ModifyPlan(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse) { +func (r *indexResource) ModifyPlan(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse) { r.SetTagsAll(ctx, request, response) } diff --git a/internal/service/resourceexplorer2/index_test.go b/internal/service/resourceexplorer2/index_test.go index ecee8f5bb1ff..beb0040b7ad2 100644 --- a/internal/service/resourceexplorer2/index_test.go +++ b/internal/service/resourceexplorer2/index_test.go @@ -152,6 +152,11 @@ func testAccIndex_type(t *testing.T) { resource.TestCheckResourceAttr(resourceName, names.AttrType, "LOCAL"), ), }, + { + Config: testAccIndexConfig_type("AGGREGATOR"), + ExpectError: regexache.MustCompile("cool down period has expired"), + Check: testAccCheckIndexDestroy(ctx), + }, }, }) } diff --git a/internal/service/resourceexplorer2/resourceexplorer2_test.go b/internal/service/resourceexplorer2/resourceexplorer2_test.go index 6e674447988d..08c0925ffe4f 100644 --- a/internal/service/resourceexplorer2/resourceexplorer2_test.go +++ b/internal/service/resourceexplorer2/resourceexplorer2_test.go @@ -10,8 +10,6 @@ import ( ) func TestAccResourceExplorer2_serial(t *testing.T) { - t.Parallel() - testCases := map[string]map[string]func(t *testing.T){ "Index": { acctest.CtBasic: testAccIndex_basic, @@ -24,6 +22,7 @@ func TestAccResourceExplorer2_serial(t *testing.T) { "defaultView": testAccView_defaultView, acctest.CtDisappears: testAccView_disappears, "filter": testAccView_filter, + "scope": testAccView_scope, "tags": testAccView_tags, }, "SearchDataSource": { diff --git a/internal/service/resourceexplorer2/service_package_gen.go b/internal/service/resourceexplorer2/service_package_gen.go index 841b5454dab2..fcaf6bdd81e8 100644 --- a/internal/service/resourceexplorer2/service_package_gen.go +++ b/internal/service/resourceexplorer2/service_package_gen.go @@ -26,14 +26,14 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.Serv func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { return []*types.ServicePackageFrameworkResource{ { - Factory: newResourceIndex, + Factory: newIndexResource, Name: "Index", Tags: &types.ServicePackageResourceTags{ IdentifierAttribute: names.AttrID, }, }, { - Factory: newResourceView, + Factory: newViewResource, Name: "View", Tags: &types.ServicePackageResourceTags{ IdentifierAttribute: names.AttrID, diff --git a/internal/service/resourceexplorer2/sweep.go b/internal/service/resourceexplorer2/sweep.go index 4bc04fcea777..95dbb72504de 100644 --- a/internal/service/resourceexplorer2/sweep.go +++ b/internal/service/resourceexplorer2/sweep.go @@ -47,7 +47,7 @@ func sweepIndexes(region string) error { } for _, v := range page.Indexes { - sweepResources = append(sweepResources, framework.NewSweepResource(newResourceIndex, client, + sweepResources = append(sweepResources, framework.NewSweepResource(newIndexResource, client, framework.NewAttribute(names.AttrARN, aws.ToString(v.Arn)), )) } diff --git a/internal/service/resourceexplorer2/view.go b/internal/service/resourceexplorer2/view.go index 793580c0ad7d..414ac271d1c8 100644 --- a/internal/service/resourceexplorer2/view.go +++ b/internal/service/resourceexplorer2/view.go @@ -24,12 +24,12 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + sdkid "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" "github.com/hashicorp/terraform-provider-aws/internal/framework" - "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" @@ -38,19 +38,20 @@ import ( // @FrameworkResource(name="View") // @Tags(identifierAttribute="id") -func newResourceView(context.Context) (resource.ResourceWithConfigure, error) { - return &resourceView{}, nil +func newViewResource(context.Context) (resource.ResourceWithConfigure, error) { + return &viewResource{}, nil } -type resourceView struct { +type viewResource struct { framework.ResourceWithConfigure + framework.WithImportByID } -func (r *resourceView) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { +func (*viewResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { response.TypeName = "aws_resourceexplorer2_view" } -func (r *resourceView) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { +func (r *viewResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { response.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ names.AttrARN: schema.StringAttribute{ @@ -75,6 +76,10 @@ func (r *resourceView) Schema(ctx context.Context, request resource.SchemaReques stringvalidator.RegexMatches(regexache.MustCompile(`^[0-9A-Za-z-]+$`), `can include letters, digits, and the dash (-) character`), }, }, + names.AttrScope: schema.StringAttribute{ + Optional: true, + Computed: true, + }, names.AttrTags: tftags.TagsAttribute(), names.AttrTagsAll: tftags.TagsAttributeComputedOnly(), }, @@ -110,11 +115,9 @@ func (r *resourceView) Schema(ctx context.Context, request resource.SchemaReques } } -func (r *resourceView) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { +func (r *viewResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { var data viewResourceModel - response.Diagnostics.Append(request.Plan.Get(ctx, &data)...) - if response.Diagnostics.HasError() { return } @@ -122,12 +125,12 @@ func (r *resourceView) Create(ctx context.Context, request resource.CreateReques conn := r.Meta().ResourceExplorer2Client(ctx) input := &resourceexplorer2.CreateViewInput{} - response.Diagnostics.Append(flex.Expand(ctx, data, input)...) + response.Diagnostics.Append(fwflex.Expand(ctx, data, input)...) if response.Diagnostics.HasError() { return } - input.ClientToken = aws.String(id.UniqueId()) + input.ClientToken = aws.String(sdkid.UniqueId()) input.Tags = getTagsIn(ctx) output, err := conn.CreateView(ctx, input) @@ -139,6 +142,10 @@ func (r *resourceView) Create(ctx context.Context, request resource.CreateReques } arn := aws.ToString(output.View.ViewArn) + // Set values for unknowns. + data.Scope = types.StringValue(aws.ToString(output.View.Scope)) + data.ViewARN = types.StringValue(arn) + data.setID() if data.DefaultView.ValueBool() { input := &resourceexplorer2.AssociateDefaultViewInput{ @@ -148,24 +155,19 @@ func (r *resourceView) Create(ctx context.Context, request resource.CreateReques _, err := conn.AssociateDefaultView(ctx, input) if err != nil { + response.State.SetAttribute(ctx, path.Root(names.AttrID), data.ID) // Set 'id' so as to taint the resource. response.Diagnostics.AddError(fmt.Sprintf("setting Resource Explorer View (%s) as the default", arn), err.Error()) return } } - // Set values for unknowns. - data.ViewARN = types.StringValue(arn) - data.setID() - response.Diagnostics.Append(response.State.Set(ctx, &data)...) } -func (r *resourceView) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { +func (r *viewResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { var data viewResourceModel - response.Diagnostics.Append(request.State.Get(ctx, &data)...) - if response.Diagnostics.HasError() { return } @@ -213,7 +215,8 @@ func (r *resourceView) Read(ctx context.Context, request resource.ReadRequest, r if view.Filters != nil && len(aws.ToString(view.Filters.FilterString)) == 0 { view.Filters = nil } - response.Diagnostics.Append(flex.Flatten(ctx, view, &data)...) + + response.Diagnostics.Append(fwflex.Flatten(ctx, view, &data)...) if response.Diagnostics.HasError() { return } @@ -225,26 +228,26 @@ func (r *resourceView) Read(ctx context.Context, request resource.ReadRequest, r response.Diagnostics.Append(response.State.Set(ctx, &data)...) } -func (r *resourceView) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { +func (r *viewResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { var old, new viewResourceModel - response.Diagnostics.Append(request.State.Get(ctx, &old)...) - if response.Diagnostics.HasError() { return } - response.Diagnostics.Append(request.Plan.Get(ctx, &new)...) - if response.Diagnostics.HasError() { return } + if new.Scope.IsUnknown() { + new.Scope = types.StringValue(old.Scope.ValueString()) + } + conn := r.Meta().ResourceExplorer2Client(ctx) if !new.Filters.Equal(old.Filters) || !new.IncludedProperties.Equal(old.IncludedProperties) { input := &resourceexplorer2.UpdateViewInput{} - response.Diagnostics.Append(flex.Expand(ctx, new, input)...) + response.Diagnostics.Append(fwflex.Expand(ctx, new, input)...) if response.Diagnostics.HasError() { return } @@ -261,7 +264,7 @@ func (r *resourceView) Update(ctx context.Context, request resource.UpdateReques if !new.DefaultView.Equal(old.DefaultView) { if new.DefaultView.ValueBool() { input := &resourceexplorer2.AssociateDefaultViewInput{ - ViewArn: flex.StringFromFramework(ctx, new.ViewARN), + ViewArn: fwflex.StringFromFramework(ctx, new.ViewARN), } _, err := conn.AssociateDefaultView(ctx, input) @@ -287,11 +290,9 @@ func (r *resourceView) Update(ctx context.Context, request resource.UpdateReques response.Diagnostics.Append(response.State.Set(ctx, &new)...) } -func (r *resourceView) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { +func (r *viewResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { var data viewResourceModel - response.Diagnostics.Append(request.State.Get(ctx, &data)...) - if response.Diagnostics.HasError() { return } @@ -302,9 +303,13 @@ func (r *resourceView) Delete(ctx context.Context, request resource.DeleteReques names.AttrID: data.ID.ValueString(), }) _, err := conn.DeleteView(ctx, &resourceexplorer2.DeleteViewInput{ - ViewArn: flex.StringFromFramework(ctx, data.ViewARN), + ViewArn: fwflex.StringFromFramework(ctx, data.ViewARN), }) + if errs.IsA[*awstypes.UnauthorizedException](err) { + return + } + if err != nil { response.Diagnostics.AddError(fmt.Sprintf("deleting Resource Explorer View (%s)", data.ID.ValueString()), err.Error()) @@ -312,11 +317,7 @@ func (r *resourceView) Delete(ctx context.Context, request resource.DeleteReques } } -func (r *resourceView) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root(names.AttrID), request, response) -} - -func (r *resourceView) ModifyPlan(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse) { +func (r *viewResource) ModifyPlan(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse) { r.SetTagsAll(ctx, request, response) } @@ -326,10 +327,11 @@ type viewResourceModel struct { Filters fwtypes.ListNestedObjectValueOf[searchFilterModel] `tfsdk:"filters"` ID types.String `tfsdk:"id"` IncludedProperties fwtypes.ListNestedObjectValueOf[includedPropertyModel] `tfsdk:"included_property"` - ViewARN types.String `tfsdk:"arn"` - ViewName types.String `tfsdk:"name"` + Scope types.String `tfsdk:"scope"` Tags tftags.Map `tfsdk:"tags"` TagsAll tftags.Map `tfsdk:"tags_all"` + ViewARN types.String `tfsdk:"arn"` + ViewName types.String `tfsdk:"name"` } func (data *viewResourceModel) InitFromID() error { diff --git a/internal/service/resourceexplorer2/view_test.go b/internal/service/resourceexplorer2/view_test.go index cd45698fcce6..193320818976 100644 --- a/internal/service/resourceexplorer2/view_test.go +++ b/internal/service/resourceexplorer2/view_test.go @@ -229,6 +229,38 @@ func testAccView_tags(t *testing.T) { }) } +func testAccView_scope(t *testing.T) { + ctx := acctest.Context(t) + var v resourceexplorer2.GetViewOutput + resourceName := "aws_resourceexplorer2_view.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.ResourceExplorer2EndpointID) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ResourceExplorer2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckViewDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccViewConfig_orgScopedView(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckViewExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), + resource.TestCheckResourceAttrSet(resourceName, names.AttrScope), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckViewDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).ResourceExplorer2Client(ctx) @@ -386,3 +418,25 @@ resource "aws_resourceexplorer2_view" "test" { } `, rName, tagKey1, tagValue1, tagKey2, tagValue2) } + +func testAccViewConfig_orgScopedView(rName string) string { + return fmt.Sprintf(` +data "aws_caller_identity" "current" {} +data "aws_partition" "current" {} + +resource "aws_resourceexplorer2_index" "test" { + type = "LOCAL" + + tags = { + Name = %[1]q + } +} + +resource "aws_resourceexplorer2_view" "test" { + name = %[1]q + scope = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:root" + + depends_on = [aws_resourceexplorer2_index.test] +} +`, rName) +} diff --git a/website/docs/r/resourceexplorer2_view.html.markdown b/website/docs/r/resourceexplorer2_view.html.markdown index 5897289eec9b..de518c217d20 100644 --- a/website/docs/r/resourceexplorer2_view.html.markdown +++ b/website/docs/r/resourceexplorer2_view.html.markdown @@ -40,6 +40,7 @@ This resource supports the following arguments: * `filters` - (Optional) Specifies which resources are included in the results of queries made using this view. See [Filters](#filters) below for more details. * `included_property` - (Optional) Optional fields to be included in search results from this view. See [Included Properties](#included-properties) below for more details. * `name` - (Required) The name of the view. The name must be no more than 64 characters long, and can include letters, digits, and the dash (-) character. The name must be unique within its AWS Region. +* `scope`- (Optional) The root ARN of the account, an organizational unit (OU), or an organization ARN. If left empty, the default is account. * `tags` - (Optional) Key-value map of resource tags. 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. ### Filters