diff --git a/.changelog/45548.txt b/.changelog/45548.txt new file mode 100644 index 000000000000..a9ec7db6e33c --- /dev/null +++ b/.changelog/45548.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_cleanrooms_collaboration: Add resource identity support +``` \ No newline at end of file diff --git a/internal/service/cleanrooms/collaboration.go b/internal/service/cleanrooms/collaboration.go index a56a5fb4d71c..de5568c1f66c 100644 --- a/internal/service/cleanrooms/collaboration.go +++ b/internal/service/cleanrooms/collaboration.go @@ -30,6 +30,9 @@ import ( // @SDKResource("aws_cleanrooms_collaboration", name="Collaboration") // @Tags(identifierAttribute="arn") // @Testing(tagsTest=false) +// @IdentityAttribute("id") +// @Testing(existsType="github.com/aws/aws-sdk-go-v2/service/cleanrooms;cleanrooms.GetCollaborationOutput") +// @Testing(preIdentityVersion="v6.26.0") func ResourceCollaboration() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceCollaborationCreate, @@ -37,10 +40,6 @@ func ResourceCollaboration() *schema.Resource { UpdateWithoutTimeout: resourceCollaborationUpdate, DeleteWithoutTimeout: resourceCollaborationDelete, - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(1 * time.Minute), Update: schema.DefaultTimeout(1 * time.Minute), diff --git a/internal/service/cleanrooms/collaboration_identity_gen_test.go b/internal/service/cleanrooms/collaboration_identity_gen_test.go new file mode 100644 index 000000000000..5be146e2da26 --- /dev/null +++ b/internal/service/cleanrooms/collaboration_identity_gen_test.go @@ -0,0 +1,311 @@ +// Copyright IBM Corp. 2014, 2025 +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by internal/generate/identitytests/main.go; DO NOT EDIT. + +package cleanrooms_test + +import ( + "testing" + + "github.com/aws/aws-sdk-go-v2/service/cleanrooms" + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" + "github.com/hashicorp/terraform-plugin-testing/tfversion" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + tfknownvalue "github.com/hashicorp/terraform-provider-aws/internal/acctest/knownvalue" + tfstatecheck "github.com/hashicorp/terraform-provider-aws/internal/acctest/statecheck" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccCleanRoomsCollaboration_Identity_Basic(t *testing.T) { + ctx := acctest.Context(t) + + var v cleanrooms.GetCollaborationOutput + resourceName := "aws_cleanrooms_collaboration.test" + rName := acctest.RandomWithPrefix(t, acctest.ResourcePrefix) + + acctest.ParallelTest(ctx, t, resource.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_12_0), + }, + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.CleanRoomsServiceID), + CheckDestroy: testAccCheckCollaborationDestroy(ctx), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + // Step 1: Setup + { + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/basic/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCollaborationExists(ctx, resourceName, &v), + ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(acctest.Region())), + statecheck.ExpectIdentity(resourceName, map[string]knownvalue.Check{ + names.AttrAccountID: tfknownvalue.AccountID(), + names.AttrRegion: knownvalue.StringExact(acctest.Region()), + names.AttrID: knownvalue.NotNull(), + }), + statecheck.ExpectIdentityValueMatchesState(resourceName, tfjsonpath.New(names.AttrID)), + }, + }, + + // Step 2: Import command + { + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/basic/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + }, + ImportStateKind: resource.ImportCommandWithID, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + + // Step 3: Import block with Import ID + { + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/basic/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + }, + ResourceName: resourceName, + ImportState: true, + ImportStateKind: resource.ImportBlockWithID, + ImportPlanChecks: resource.ImportPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrID), knownvalue.NotNull()), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(acctest.Region())), + }, + }, + }, + + // Step 4: Import block with Resource Identity + { + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/basic/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + }, + ResourceName: resourceName, + ImportState: true, + ImportStateKind: resource.ImportBlockWithResourceIdentity, + ImportPlanChecks: resource.ImportPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrID), knownvalue.NotNull()), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(acctest.Region())), + }, + }, + }, + }, + }) +} + +func TestAccCleanRoomsCollaboration_Identity_RegionOverride(t *testing.T) { + ctx := acctest.Context(t) + + resourceName := "aws_cleanrooms_collaboration.test" + rName := acctest.RandomWithPrefix(t, acctest.ResourcePrefix) + + acctest.ParallelTest(ctx, t, resource.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_12_0), + }, + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.CleanRoomsServiceID), + CheckDestroy: acctest.CheckDestroyNoop, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + // Step 1: Setup + { + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/region_override/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + "region": config.StringVariable(acctest.AlternateRegion()), + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(acctest.AlternateRegion())), + statecheck.ExpectIdentity(resourceName, map[string]knownvalue.Check{ + names.AttrAccountID: tfknownvalue.AccountID(), + names.AttrRegion: knownvalue.StringExact(acctest.AlternateRegion()), + names.AttrID: knownvalue.NotNull(), + }), + statecheck.ExpectIdentityValueMatchesState(resourceName, tfjsonpath.New(names.AttrID)), + }, + }, + + // Step 2: Import command + { + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/region_override/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + "region": config.StringVariable(acctest.AlternateRegion()), + }, + ImportStateKind: resource.ImportCommandWithID, + ImportStateIdFunc: acctest.CrossRegionImportStateIdFunc(resourceName), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + + // Step 3: Import block with Import ID + { + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/region_override/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + "region": config.StringVariable(acctest.AlternateRegion()), + }, + ResourceName: resourceName, + ImportState: true, + ImportStateKind: resource.ImportBlockWithID, + ImportStateIdFunc: acctest.CrossRegionImportStateIdFunc(resourceName), + ImportPlanChecks: resource.ImportPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrID), knownvalue.NotNull()), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(acctest.AlternateRegion())), + }, + }, + }, + + // Step 4: Import block with Resource Identity + { + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/region_override/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + "region": config.StringVariable(acctest.AlternateRegion()), + }, + ResourceName: resourceName, + ImportState: true, + ImportStateKind: resource.ImportBlockWithResourceIdentity, + ImportPlanChecks: resource.ImportPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrID), knownvalue.NotNull()), + plancheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(acctest.AlternateRegion())), + }, + }, + }, + }, + }) +} + +// Resource Identity was added after v6.26.0 +func TestAccCleanRoomsCollaboration_Identity_ExistingResource(t *testing.T) { + ctx := acctest.Context(t) + + var v cleanrooms.GetCollaborationOutput + resourceName := "aws_cleanrooms_collaboration.test" + rName := acctest.RandomWithPrefix(t, acctest.ResourcePrefix) + + acctest.ParallelTest(ctx, t, resource.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_12_0), + }, + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.CleanRoomsServiceID), + CheckDestroy: testAccCheckCollaborationDestroy(ctx), + Steps: []resource.TestStep{ + // Step 1: Create pre-Identity + { + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/basic_v6.26.0/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCollaborationExists(ctx, resourceName, &v), + ), + ConfigStateChecks: []statecheck.StateCheck{ + tfstatecheck.ExpectNoIdentity(resourceName), + }, + }, + + // Step 2: Current version + { + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/basic/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + }, + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop), + }, + PostApplyPostRefresh: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectIdentity(resourceName, map[string]knownvalue.Check{ + names.AttrAccountID: tfknownvalue.AccountID(), + names.AttrRegion: knownvalue.StringExact(acctest.Region()), + names.AttrID: knownvalue.NotNull(), + }), + statecheck.ExpectIdentityValueMatchesState(resourceName, tfjsonpath.New(names.AttrID)), + }, + }, + }, + }) +} + +// Resource Identity was added after v6.26.0 +func TestAccCleanRoomsCollaboration_Identity_ExistingResource_NoRefresh_NoChange(t *testing.T) { + ctx := acctest.Context(t) + + var v cleanrooms.GetCollaborationOutput + resourceName := "aws_cleanrooms_collaboration.test" + rName := acctest.RandomWithPrefix(t, acctest.ResourcePrefix) + + acctest.ParallelTest(ctx, t, resource.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_12_0), + }, + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.CleanRoomsServiceID), + CheckDestroy: testAccCheckCollaborationDestroy(ctx), + AdditionalCLIOptions: &resource.AdditionalCLIOptions{ + Plan: resource.PlanOptions{ + NoRefresh: true, + }, + }, + Steps: []resource.TestStep{ + // Step 1: Create pre-Identity + { + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/basic_v6.26.0/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + }, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCollaborationExists(ctx, resourceName, &v), + ), + ConfigStateChecks: []statecheck.StateCheck{ + tfstatecheck.ExpectNoIdentity(resourceName), + }, + }, + + // Step 2: Current version + { + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + ConfigDirectory: config.StaticDirectory("testdata/Collaboration/basic/"), + ConfigVariables: config.Variables{ + acctest.CtRName: config.StringVariable(rName), + }, + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop), + }, + PostApplyPostRefresh: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop), + }, + }, + ConfigStateChecks: []statecheck.StateCheck{ + tfstatecheck.ExpectNoIdentity(resourceName), + }, + }, + }, + }) +} diff --git a/internal/service/cleanrooms/service_package_gen.go b/internal/service/cleanrooms/service_package_gen.go index 8348fb0f7515..941ea8ad677b 100644 --- a/internal/service/cleanrooms/service_package_gen.go +++ b/internal/service/cleanrooms/service_package_gen.go @@ -51,7 +51,11 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*inttypes.ServicePa Tags: unique.Make(inttypes.ServicePackageResourceTags{ IdentifierAttribute: names.AttrARN, }), - Region: unique.Make(inttypes.ResourceRegionDefault()), + Region: unique.Make(inttypes.ResourceRegionDefault()), + Identity: inttypes.RegionalSingleParameterIdentity(names.AttrID), + Import: inttypes.SDKv2Import{ + WrappedImport: true, + }, }, { Factory: ResourceConfiguredTable, diff --git a/internal/service/cleanrooms/testdata/Collaboration/basic/main_gen.tf b/internal/service/cleanrooms/testdata/Collaboration/basic/main_gen.tf new file mode 100644 index 000000000000..0ee135c75001 --- /dev/null +++ b/internal/service/cleanrooms/testdata/Collaboration/basic/main_gen.tf @@ -0,0 +1,23 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resource "aws_cleanrooms_collaboration" "test" { + name = var.rName + creator_member_abilities = ["CAN_QUERY", "CAN_RECEIVE_RESULTS"] + creator_display_name = var.rName + description = var.rName + query_log_status = "DISABLED" + analytics_engine = "SPARK" + + data_encryption_metadata { + allow_clear_text = true + allow_duplicates = true + allow_joins_on_columns_with_different_names = true + preserve_nulls = false + } +} +variable "rName" { + description = "Name for resource" + type = string + nullable = false +} diff --git a/internal/service/cleanrooms/testdata/Collaboration/basic_v6.26.0/main_gen.tf b/internal/service/cleanrooms/testdata/Collaboration/basic_v6.26.0/main_gen.tf new file mode 100644 index 000000000000..f4f14e51ea14 --- /dev/null +++ b/internal/service/cleanrooms/testdata/Collaboration/basic_v6.26.0/main_gen.tf @@ -0,0 +1,33 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resource "aws_cleanrooms_collaboration" "test" { + name = var.rName + creator_member_abilities = ["CAN_QUERY", "CAN_RECEIVE_RESULTS"] + creator_display_name = var.rName + description = var.rName + query_log_status = "DISABLED" + analytics_engine = "SPARK" + + data_encryption_metadata { + allow_clear_text = true + allow_duplicates = true + allow_joins_on_columns_with_different_names = true + preserve_nulls = false + } +} +variable "rName" { + description = "Name for resource" + type = string + nullable = false +} +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "6.26.0" + } + } +} + +provider "aws" {} diff --git a/internal/service/cleanrooms/testdata/Collaboration/region_override/main_gen.tf b/internal/service/cleanrooms/testdata/Collaboration/region_override/main_gen.tf new file mode 100644 index 000000000000..ec879f7637d7 --- /dev/null +++ b/internal/service/cleanrooms/testdata/Collaboration/region_override/main_gen.tf @@ -0,0 +1,31 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resource "aws_cleanrooms_collaboration" "test" { + region = var.region + + name = var.rName + creator_member_abilities = ["CAN_QUERY", "CAN_RECEIVE_RESULTS"] + creator_display_name = var.rName + description = var.rName + query_log_status = "DISABLED" + analytics_engine = "SPARK" + + data_encryption_metadata { + allow_clear_text = true + allow_duplicates = true + allow_joins_on_columns_with_different_names = true + preserve_nulls = false + } +} +variable "rName" { + description = "Name for resource" + type = string + nullable = false +} + +variable "region" { + description = "Region to deploy resource in" + type = string + nullable = false +} diff --git a/internal/service/cleanrooms/testdata/tmpl/collaboration_tags.gtpl b/internal/service/cleanrooms/testdata/tmpl/collaboration_tags.gtpl new file mode 100644 index 000000000000..00201a4ecb2c --- /dev/null +++ b/internal/service/cleanrooms/testdata/tmpl/collaboration_tags.gtpl @@ -0,0 +1,18 @@ +resource "aws_cleanrooms_collaboration" "test" { +{{- template "region" }} + name = var.rName + creator_member_abilities = ["CAN_QUERY", "CAN_RECEIVE_RESULTS"] + creator_display_name = var.rName + description = var.rName + query_log_status = "DISABLED" + analytics_engine = "SPARK" + + data_encryption_metadata { + allow_clear_text = true + allow_duplicates = true + allow_joins_on_columns_with_different_names = true + preserve_nulls = false + } + +{{- template "tags" }} +} \ No newline at end of file diff --git a/website/docs/r/cleanrooms_collaboration.html.markdown b/website/docs/r/cleanrooms_collaboration.html.markdown index 03b07b4a6233..36dfdfb575fd 100644 --- a/website/docs/r/cleanrooms_collaboration.html.markdown +++ b/website/docs/r/cleanrooms_collaboration.html.markdown @@ -91,6 +91,32 @@ This resource exports the following attributes in addition to the arguments abov ## Import +In Terraform v1.12.0 and later, the [`import` block](https://developer.hashicorp.com/terraform/language/import) can be used with the `identity` attribute. For example: + +```terraform +import { + to = aws_cleanrooms_collaboration.collaboration + identity = { + id = "1234abcd-12ab-34cd-56ef-1234567890ab" + } +} + +resource "aws_cleanrooms_collaboration" "collaboration" { + ### Configuration omitted for brevity ### +} +``` + +### Identity Schema + +#### Required + +* `id` - (String) ID of the cleanrooms collaboration. + +#### Optional + +* `account_id` (String) AWS Account where this resource is managed. +* `region` (String) Region where this resource is managed. + In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import `aws_cleanrooms_collaboration` using the `id`. For example: ```terraform