diff --git a/.changelog/39620.txt b/.changelog/39620.txt new file mode 100644 index 00000000000..ec1124d951f --- /dev/null +++ b/.changelog/39620.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_pinpointsmsvoicev2_configuration_set +``` \ No newline at end of file diff --git a/internal/service/pinpointsmsvoicev2/configuration_set.go b/internal/service/pinpointsmsvoicev2/configuration_set.go new file mode 100644 index 00000000000..b4bd9f9d399 --- /dev/null +++ b/internal/service/pinpointsmsvoicev2/configuration_set.go @@ -0,0 +1,339 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package pinpointsmsvoicev2 + +import ( + "context" + "fmt" + + "github.com/YakDriver/regexache" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2" + awstypes "github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2/types" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "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/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + 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" + 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" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkResource("aws_pinpointsmsvoicev2_configuration_set", name="Configuration Set") +// @Tags(identifierAttribute="arn") +func newConfigurationSetResource(context.Context) (resource.ResourceWithConfigure, error) { + r := &configurationSetResource{} + + return r, nil +} + +type configurationSetResource struct { + framework.ResourceWithConfigure + framework.WithImportByID +} + +func (*configurationSetResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { + response.TypeName = "aws_pinpointsmsvoicev2_configuration_set" +} + +func (r *configurationSetResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { + response.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + names.AttrARN: framework.ARNAttributeComputedOnly(), + "default_message_type": schema.StringAttribute{ + Optional: true, + CustomType: fwtypes.StringEnumType[awstypes.MessageType](), + Validators: []validator.String{ + stringvalidator.RegexMatches(regexache.MustCompile(`^(TRANSACTIONAL|PROMOTIONAL)$`), "must be either TRANSACTIONAL or PROMOTIONAL"), + }, + }, + "default_sender_id": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexache.MustCompile(`^[A-Za-z0-9_-]{1,11}$`), "must be between 1 and 11 characters long and contain only letters, numbers, underscores, and dashes"), + }, + }, + names.AttrID: framework.IDAttribute(), + names.AttrName: schema.StringAttribute{ + Required: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexache.MustCompile(`^[A-Za-z0-9][A-Za-z0-9_\-]{0,63}$`), ""), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + names.AttrTags: tftags.TagsAttribute(), + names.AttrTagsAll: tftags.TagsAttributeComputedOnly(), + }, + } +} + +func (r *configurationSetResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { + var data configurationSetResourceModel + response.Diagnostics.Append(request.Plan.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + conn := r.Meta().PinpointSMSVoiceV2Client(ctx) + + name := data.ConfigurationSetName.ValueString() + input := &pinpointsmsvoicev2.CreateConfigurationSetInput{ + ClientToken: aws.String(sdkid.UniqueId()), + ConfigurationSetName: aws.String(name), + Tags: getTagsIn(ctx), + } + + output, err := conn.CreateConfigurationSet(ctx, input) + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("creating End User Messaging SMS Configuration Set (%s)", name), err.Error()) + + return + } + + // Set values for unknowns. + data.ConfigurationSetARN = fwflex.StringToFramework(ctx, output.ConfigurationSetArn) + data.setID() + + response.Diagnostics.Append(response.State.Set(ctx, data)...) +} + +func (r *configurationSetResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { + var data configurationSetResourceModel + response.Diagnostics.Append(request.State.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + if err := data.InitFromID(); err != nil { + response.Diagnostics.AddError("parsing resource ID", err.Error()) + + return + } + + conn := r.Meta().PinpointSMSVoiceV2Client(ctx) + + out, err := findConfigurationSetByID(ctx, conn, data.ID.ValueString()) + + if tfresource.NotFound(err) { + response.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err)) + response.State.RemoveResource(ctx) + + return + } + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("reading End User Messaging SMS Configuration Set (%s)", data.ID.ValueString()), err.Error()) + + return + } + + // Set attributes for import. + response.Diagnostics.Append(fwflex.Flatten(ctx, out, &data)...) + if response.Diagnostics.HasError() { + return + } + + response.Diagnostics.Append(response.State.Set(ctx, &data)...) +} + +func (r *configurationSetResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { + var old, new configurationSetResourceModel + response.Diagnostics.Append(request.Plan.Get(ctx, &new)...) + if response.Diagnostics.HasError() { + return + } + response.Diagnostics.Append(request.State.Get(ctx, &old)...) + if response.Diagnostics.HasError() { + return + } + + conn := r.Meta().PinpointSMSVoiceV2Client(ctx) + + name := new.ConfigurationSetName.ValueString() + if !new.DefaultSenderID.Equal(old.DefaultSenderID) { + if new.DefaultSenderID.IsNull() { + err := deleteDefaultSenderID(ctx, conn, name) + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("deleting default sender ID for End User Messaging SMS Configuration Set (%s)", name), err.Error()) + + return + } + } else { + err := setDefaultSenderID(ctx, conn, name, new.DefaultSenderID.ValueString()) + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("setting default sender ID for End User Messaging SMS Configuration Set (%s) to %s", name, new.DefaultSenderID.ValueString()), err.Error()) + + return + } + } + } + if !new.DefaultMessageType.Equal(old.DefaultMessageType) { + if new.DefaultMessageType.IsNull() { + err := deleteDefaultMessageType(ctx, conn, name) + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("deleting default message type for End User Messaging SMS Configuration Set (%s)", name), err.Error()) + + return + } + } else { + err := setDefaultMessageType(ctx, conn, name, new.DefaultMessageType.ValueEnum()) + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("setting default message type for End User Messaging SMS Configuration Set (%s) to %s", name, new.DefaultMessageType.ValueString()), err.Error()) + + return + } + } + } + + response.Diagnostics.Append(response.State.Set(ctx, &new)...) +} + +func (r *configurationSetResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { + var data configurationSetResourceModel + response.Diagnostics.Append(request.State.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + conn := r.Meta().PinpointSMSVoiceV2Client(ctx) + + _, err := conn.DeleteConfigurationSet(ctx, &pinpointsmsvoicev2.DeleteConfigurationSetInput{ + ConfigurationSetName: data.ID.ValueStringPointer(), + }) + + if errs.IsA[*awstypes.ResourceNotFoundException](err) { + return + } + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("deleting End User Messaging SMS Configuration Set (%s)", data.ID.ValueString()), err.Error()) + + return + } +} + +func (r *configurationSetResource) ModifyPlan(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse) { + r.SetTagsAll(ctx, request, response) +} + +type configurationSetResourceModel struct { + ID types.String `tfsdk:"id"` + ConfigurationSetARN types.String `tfsdk:"arn"` + ConfigurationSetName types.String `tfsdk:"name"` + DefaultMessageType fwtypes.StringEnum[awstypes.MessageType] `tfsdk:"default_message_type"` + DefaultSenderID types.String `tfsdk:"default_sender_id"` + Tags tftags.Map `tfsdk:"tags"` + TagsAll tftags.Map `tfsdk:"tags_all"` +} + +func (model *configurationSetResourceModel) InitFromID() error { + model.ConfigurationSetName = model.ID + + return nil +} + +func (model *configurationSetResourceModel) setID() { + model.ID = model.ConfigurationSetName +} + +func findConfigurationSetByID(ctx context.Context, conn *pinpointsmsvoicev2.Client, id string) (*awstypes.ConfigurationSetInformation, error) { + input := &pinpointsmsvoicev2.DescribeConfigurationSetsInput{ + ConfigurationSetNames: []string{id}, + } + + return findConfigurationSet(ctx, conn, input) +} + +func findConfigurationSet(ctx context.Context, conn *pinpointsmsvoicev2.Client, input *pinpointsmsvoicev2.DescribeConfigurationSetsInput) (*awstypes.ConfigurationSetInformation, error) { + output, err := findConfigurationSets(ctx, conn, input) + + if err != nil { + return nil, err + } + + return tfresource.AssertSingleValueResult(output) +} + +func findConfigurationSets(ctx context.Context, conn *pinpointsmsvoicev2.Client, input *pinpointsmsvoicev2.DescribeConfigurationSetsInput) ([]awstypes.ConfigurationSetInformation, error) { + var output []awstypes.ConfigurationSetInformation + + pages := pinpointsmsvoicev2.NewDescribeConfigurationSetsPaginator(conn, input) + for pages.HasMorePages() { + page, err := pages.NextPage(ctx) + + if errs.IsA[*awstypes.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + output = append(output, page.ConfigurationSets...) + } + + return output, nil +} + +func setDefaultSenderID(ctx context.Context, conn *pinpointsmsvoicev2.Client, configurationSetName, senderID string) error { + input := &pinpointsmsvoicev2.SetDefaultSenderIdInput{ + ConfigurationSetName: aws.String(configurationSetName), + SenderId: aws.String(senderID), + } + + _, err := conn.SetDefaultSenderId(ctx, input) + + return err +} + +func setDefaultMessageType(ctx context.Context, conn *pinpointsmsvoicev2.Client, configurationSetName string, messageType awstypes.MessageType) error { + input := &pinpointsmsvoicev2.SetDefaultMessageTypeInput{ + ConfigurationSetName: aws.String(configurationSetName), + MessageType: messageType, + } + + _, err := conn.SetDefaultMessageType(ctx, input) + + return err +} + +func deleteDefaultSenderID(ctx context.Context, conn *pinpointsmsvoicev2.Client, configurationSetName string) error { + input := &pinpointsmsvoicev2.DeleteDefaultSenderIdInput{ + ConfigurationSetName: aws.String(configurationSetName), + } + + _, err := conn.DeleteDefaultSenderId(ctx, input) + + return err +} + +func deleteDefaultMessageType(ctx context.Context, conn *pinpointsmsvoicev2.Client, configurationSetName string) error { + input := &pinpointsmsvoicev2.DeleteDefaultMessageTypeInput{ + ConfigurationSetName: aws.String(configurationSetName), + } + + _, err := conn.DeleteDefaultMessageType(ctx, input) + + return err +} diff --git a/internal/service/pinpointsmsvoicev2/configuration_set_test.go b/internal/service/pinpointsmsvoicev2/configuration_set_test.go new file mode 100644 index 00000000000..66b4d3ea5c2 --- /dev/null +++ b/internal/service/pinpointsmsvoicev2/configuration_set_test.go @@ -0,0 +1,241 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package pinpointsmsvoicev2_test + +import ( + "context" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2" + awstypes "github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2/types" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfpinpointsmsvoicev2 "github.com/hashicorp/terraform-provider-aws/internal/service/pinpointsmsvoicev2" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccPinpointSMSVoiceV2ConfigurationSet_basic(t *testing.T) { + ctx := acctest.Context(t) + var configurationSet awstypes.ConfigurationSetInformation + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_pinpointsmsvoicev2_configuration_set.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + testAccPreCheckConfigurationSet(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.PinpointSMSVoiceV2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckConfigurationSetDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccConfigurationSetConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckConfigurationSetExists(ctx, resourceName, &configurationSet), + ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrARN), knownvalue.NotNull()), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrName), knownvalue.StringExact(rName)), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.Null()), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{})), + }, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccPinpointSMSVoiceV2ConfigurationSet_disappears(t *testing.T) { + ctx := acctest.Context(t) + var configurationSet awstypes.ConfigurationSetInformation + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_pinpointsmsvoicev2_configuration_set.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + testAccPreCheckConfigurationSet(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.PinpointSMSVoiceV2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckConfigurationSetDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccConfigurationSetConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckConfigurationSetExists(ctx, resourceName, &configurationSet), + acctest.CheckFrameworkResourceDisappears(ctx, acctest.Provider, tfpinpointsmsvoicev2.ResourceConfigurationSet, resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccPinpointSMSVoiceV2ConfigurationSet_tags(t *testing.T) { + ctx := acctest.Context(t) + var configurationSet awstypes.ConfigurationSetInformation + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_pinpointsmsvoicev2_configuration_set.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + testAccPreCheckConfigurationSet(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.PinpointSMSVoiceV2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckConfigurationSetDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccConfigurationSetConfig_tags1(rName, acctest.CtKey1, acctest.CtValue1), + Check: resource.ComposeTestCheckFunc( + testAccCheckConfigurationSetExists(ctx, resourceName, &configurationSet), + ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + acctest.CtKey1: knownvalue.StringExact(acctest.CtValue1), + })), + }, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccConfigurationSetConfig_tags2(rName, acctest.CtKey1, acctest.CtValue1Updated, acctest.CtKey2, acctest.CtValue2), + Check: resource.ComposeTestCheckFunc( + testAccCheckConfigurationSetExists(ctx, resourceName, &configurationSet), + ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + acctest.CtKey1: knownvalue.StringExact(acctest.CtValue1Updated), + acctest.CtKey2: knownvalue.StringExact(acctest.CtValue2), + })), + }, + }, + { + Config: testAccConfigurationSetConfig_tags1(rName, acctest.CtKey2, acctest.CtValue2), + Check: resource.ComposeTestCheckFunc( + testAccCheckConfigurationSetExists(ctx, resourceName, &configurationSet), + ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{ + acctest.CtKey2: knownvalue.StringExact(acctest.CtValue2), + })), + }, + }, + }, + }) +} + +func testAccCheckConfigurationSetDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).PinpointSMSVoiceV2Client(ctx) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_pinpointsmsvoicev2_configuration_set" { + continue + } + + _, err := tfpinpointsmsvoicev2.FindConfigurationSetByID(ctx, conn, rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("End User Messaging SMS Configuration Set %s still exists", rs.Primary.ID) + } + + return nil + } +} + +func testAccCheckConfigurationSetExists(ctx context.Context, n string, v *awstypes.ConfigurationSetInformation) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).PinpointSMSVoiceV2Client(ctx) + + output, err := tfpinpointsmsvoicev2.FindConfigurationSetByID(ctx, conn, rs.Primary.ID) + + if err != nil { + return err + } + + *v = *output + + return nil + } +} + +func testAccPreCheckConfigurationSet(ctx context.Context, t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).PinpointSMSVoiceV2Client(ctx) + + input := &pinpointsmsvoicev2.DescribeConfigurationSetsInput{} + + _, err := conn.DescribeConfigurationSets(ctx, input) + + if acctest.PreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) + } + + if err != nil { + t.Fatalf("unexpected PreCheck error: %s", err) + } +} + +func testAccConfigurationSetConfig_basic(rName string) string { + return fmt.Sprintf(` +resource "aws_pinpointsmsvoicev2_configuration_set" "test" { + name = %[1]q +} +`, rName) +} + +func testAccConfigurationSetConfig_tags1(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_pinpointsmsvoicev2_configuration_set" "test" { + name = %[1]q + + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1) +} + +func testAccConfigurationSetConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_pinpointsmsvoicev2_configuration_set" "test" { + name = %[1]q + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +} diff --git a/internal/service/pinpointsmsvoicev2/exports_test.go b/internal/service/pinpointsmsvoicev2/exports_test.go index 3268085cb12..87890f1cae3 100644 --- a/internal/service/pinpointsmsvoicev2/exports_test.go +++ b/internal/service/pinpointsmsvoicev2/exports_test.go @@ -5,9 +5,11 @@ package pinpointsmsvoicev2 // Exports for use in tests only. var ( - ResourceOptOutList = newOptOutListResource - ResourcePhoneNumber = newPhoneNumberResource + ResourceConfigurationSet = newConfigurationSetResource + ResourceOptOutList = newOptOutListResource + ResourcePhoneNumber = newPhoneNumberResource - FindOptOutListByID = findOptOutListByID - FindPhoneNumberByID = findPhoneNumberByID + FindConfigurationSetByID = findConfigurationSetByID + FindOptOutListByID = findOptOutListByID + FindPhoneNumberByID = findPhoneNumberByID ) diff --git a/internal/service/pinpointsmsvoicev2/service_package_gen.go b/internal/service/pinpointsmsvoicev2/service_package_gen.go index da87ba07388..8a7120482e0 100644 --- a/internal/service/pinpointsmsvoicev2/service_package_gen.go +++ b/internal/service/pinpointsmsvoicev2/service_package_gen.go @@ -20,6 +20,13 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.Serv func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { return []*types.ServicePackageFrameworkResource{ + { + Factory: newConfigurationSetResource, + Name: "Configuration Set", + Tags: &types.ServicePackageResourceTags{ + IdentifierAttribute: names.AttrARN, + }, + }, { Factory: newOptOutListResource, Name: "Opt-out List", diff --git a/website/docs/r/pinpointsmsvoicev2_configuration_set.html.markdown b/website/docs/r/pinpointsmsvoicev2_configuration_set.html.markdown new file mode 100644 index 00000000000..546d244a6e4 --- /dev/null +++ b/website/docs/r/pinpointsmsvoicev2_configuration_set.html.markdown @@ -0,0 +1,54 @@ +--- +subcategory: "End User Messaging SMS" +layout: "aws" +page_title: "AWS: aws_pinpointsmsvoicev2_configuration_set" +description: |- + Manages an AWS End User Messaging SMS Configuration Set. +--- + +# Resource: aws_pinpointsmsvoicev2_configuration_set + +Manages an AWS End User Messaging SMS Configuration Set. + +## Example Usage + +```terraform +resource "aws_pinpointsmsvoicev2_configuration_set" "example" { + name = "example-configuration-set" + default_sender_id = "example" + default_message_type = "TRANSACTIONAL" +} +``` + +## Argument Reference + +This resource supports the following arguments: + +* `name` - (Required) The name of the configuration set. +* `default_sender_id` - (Optional) The default sender ID to use for this configuration set. +* `default_message_type` - (Optional) The default message type. Must either be "TRANSACTIONAL" or "PROMOTIONAL" +* `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. + +## Attribute Reference + +This resource exports the following attributes in addition to the arguments above: + +* `arn` - ARN of the configuration set. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block). + +## Import + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import -out lists using the `name`. For example: + +```terraform +import { + to = aws_pinpointsmsvoicev2_configuration_set.example + id = "example-configuration-set" +} +``` + +Using `terraform import`, import configuration sets using the `name`. For example: + +```console +% terraform import aws_pinpointsmsvoicev2_configuration_set.example example-configuration-set +```