From 24d70154beb51689401ef9b173cc2f81ee86f86d Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sat, 30 Jan 2021 13:39:02 +0200 Subject: [PATCH 1/6] add new resource --- .../service/sagemaker/finder/finder.go | 19 ++ .../service/sagemaker/waiter/status.go | 44 ++- .../service/sagemaker/waiter/waiter.go | 69 ++++- aws/provider.go | 1 + ...ource_aws_sagemaker_model_package_group.go | 151 ++++++++++ ..._aws_sagemaker_model_package_group_test.go | 264 ++++++++++++++++++ 6 files changed, 526 insertions(+), 22 deletions(-) create mode 100644 aws/resource_aws_sagemaker_model_package_group.go create mode 100644 aws/resource_aws_sagemaker_model_package_group_test.go diff --git a/aws/internal/service/sagemaker/finder/finder.go b/aws/internal/service/sagemaker/finder/finder.go index f7d201d2bb6..3236aa4544d 100644 --- a/aws/internal/service/sagemaker/finder/finder.go +++ b/aws/internal/service/sagemaker/finder/finder.go @@ -24,6 +24,25 @@ func CodeRepositoryByName(conn *sagemaker.SageMaker, name string) (*sagemaker.De return output, nil } +// ModelPackageGroupByName returns the code repository corresponding to the specified name. +// Returns nil if no code repository is found. +func ModelPackageGroupByName(conn *sagemaker.SageMaker, name string) (*sagemaker.DescribeModelPackageGroupOutput, error) { + input := &sagemaker.DescribeModelPackageGroupInput{ + ModelPackageGroupName: aws.String(name), + } + + output, err := conn.DescribeModelPackageGroup(input) + if err != nil { + return nil, err + } + + if output == nil { + return nil, nil + } + + return output, nil +} + // ImageByName returns the Image corresponding to the specified name. // Returns nil if no Image is found. func ImageByName(conn *sagemaker.SageMaker, name string) (*sagemaker.DescribeImageOutput, error) { diff --git a/aws/internal/service/sagemaker/waiter/status.go b/aws/internal/service/sagemaker/waiter/status.go index 5a2b5cfb363..57b7eb68f3f 100644 --- a/aws/internal/service/sagemaker/waiter/status.go +++ b/aws/internal/service/sagemaker/waiter/status.go @@ -11,15 +11,16 @@ import ( ) const ( - SagemakerNotebookInstanceStatusNotFound = "NotFound" - SagemakerImageStatusNotFound = "NotFound" - SagemakerImageStatusFailed = "Failed" - SagemakerImageVersionStatusNotFound = "NotFound" - SagemakerImageVersionStatusFailed = "Failed" - SagemakerDomainStatusNotFound = "NotFound" - SagemakerFeatureGroupStatusNotFound = "NotFound" - SagemakerFeatureGroupStatusUnknown = "Unknown" - SagemakerUserProfileStatusNotFound = "NotFound" + SagemakerNotebookInstanceStatusNotFound = "NotFound" + SagemakerImageStatusNotFound = "NotFound" + SagemakerImageStatusFailed = "Failed" + SagemakerImageVersionStatusNotFound = "NotFound" + SagemakerImageVersionStatusFailed = "Failed" + SagemakerDomainStatusNotFound = "NotFound" + SagemakerFeatureGroupStatusNotFound = "NotFound" + SagemakerFeatureGroupStatusUnknown = "Unknown" + SagemakerUserProfileStatusNotFound = "NotFound" + SagemakerModelPackageGroupStatusNotFound = "NotFound" ) // NotebookInstanceStatus fetches the NotebookInstance and its Status @@ -47,6 +48,31 @@ func NotebookInstanceStatus(conn *sagemaker.SageMaker, notebookName string) reso } } +// ModelPackageGroupStatus fetches the ModelPackageGroup and its Status +func ModelPackageGroupStatus(conn *sagemaker.SageMaker, name string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + input := &sagemaker.DescribeModelPackageGroupInput{ + ModelPackageGroupName: aws.String(name), + } + + output, err := conn.DescribeModelPackageGroup(input) + + if tfawserr.ErrMessageContains(err, "ValidationException", "does not exist") { + return nil, SagemakerModelPackageGroupStatusNotFound, nil + } + + if err != nil { + return nil, sagemaker.ModelPackageGroupStatusFailed, err + } + + if output == nil { + return nil, SagemakerModelPackageGroupStatusNotFound, nil + } + + return output, aws.StringValue(output.ModelPackageGroupStatus), nil + } +} + // ImageStatus fetches the Image and its Status func ImageStatus(conn *sagemaker.SageMaker, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { diff --git a/aws/internal/service/sagemaker/waiter/waiter.go b/aws/internal/service/sagemaker/waiter/waiter.go index e1e03df43b4..c3618d16d08 100644 --- a/aws/internal/service/sagemaker/waiter/waiter.go +++ b/aws/internal/service/sagemaker/waiter/waiter.go @@ -8,19 +8,21 @@ import ( ) const ( - NotebookInstanceInServiceTimeout = 10 * time.Minute - NotebookInstanceStoppedTimeout = 10 * time.Minute - NotebookInstanceDeletedTimeout = 10 * time.Minute - ImageCreatedTimeout = 10 * time.Minute - ImageDeletedTimeout = 10 * time.Minute - ImageVersionCreatedTimeout = 10 * time.Minute - ImageVersionDeletedTimeout = 10 * time.Minute - DomainInServiceTimeout = 10 * time.Minute - DomainDeletedTimeout = 10 * time.Minute - FeatureGroupCreatedTimeout = 10 * time.Minute - FeatureGroupDeletedTimeout = 10 * time.Minute - UserProfileInServiceTimeout = 10 * time.Minute - UserProfileDeletedTimeout = 10 * time.Minute + NotebookInstanceInServiceTimeout = 10 * time.Minute + NotebookInstanceStoppedTimeout = 10 * time.Minute + NotebookInstanceDeletedTimeout = 10 * time.Minute + ModelPackageGroupCompletedTimeout = 10 * time.Minute + ModelPackageGroupDeletedTimeout = 10 * time.Minute + ImageCreatedTimeout = 10 * time.Minute + ImageDeletedTimeout = 10 * time.Minute + ImageVersionCreatedTimeout = 10 * time.Minute + ImageVersionDeletedTimeout = 10 * time.Minute + DomainInServiceTimeout = 10 * time.Minute + DomainDeletedTimeout = 10 * time.Minute + FeatureGroupCreatedTimeout = 10 * time.Minute + FeatureGroupDeletedTimeout = 10 * time.Minute + UserProfileInServiceTimeout = 10 * time.Minute + UserProfileDeletedTimeout = 10 * time.Minute ) // NotebookInstanceInService waits for a NotebookInstance to return InService @@ -87,6 +89,47 @@ func NotebookInstanceDeleted(conn *sagemaker.SageMaker, notebookName string) (*s return nil, err } +// ModelPackageGroupCompleted waits for a ModelPackageGroup to return Created +func ModelPackageGroupCompleted(conn *sagemaker.SageMaker, name string) (*sagemaker.DescribeModelPackageGroupOutput, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + sagemaker.ModelPackageGroupStatusPending, + sagemaker.ModelPackageGroupStatusInProgress, + }, + Target: []string{sagemaker.ModelPackageGroupStatusCompleted}, + Refresh: ModelPackageGroupStatus(conn, name), + Timeout: ModelPackageGroupCompletedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*sagemaker.DescribeModelPackageGroupOutput); ok { + return output, err + } + + return nil, err +} + +// ModelPackageGroupDeleted waits for a ModelPackageGroup to return Created +func ModelPackageGroupDeleted(conn *sagemaker.SageMaker, name string) (*sagemaker.DescribeModelPackageGroupOutput, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + sagemaker.ModelPackageGroupStatusDeleting, + }, + Target: []string{}, + Refresh: ModelPackageGroupStatus(conn, name), + Timeout: ModelPackageGroupDeletedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*sagemaker.DescribeModelPackageGroupOutput); ok { + return output, err + } + + return nil, err +} + // ImageCreated waits for a Image to return Created func ImageCreated(conn *sagemaker.SageMaker, name string) (*sagemaker.DescribeImageOutput, error) { stateConf := &resource.StateChangeConf{ diff --git a/aws/provider.go b/aws/provider.go index 66a97c15473..1ba37addf07 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -888,6 +888,7 @@ func Provider() *schema.Provider { "aws_sagemaker_image": resourceAwsSagemakerImage(), "aws_sagemaker_image_version": resourceAwsSagemakerImageVersion(), "aws_sagemaker_model": resourceAwsSagemakerModel(), + "aws_sagemaker_model_package_group": resourceAwsSagemakerModelPackageGroup(), "aws_sagemaker_notebook_instance_lifecycle_configuration": resourceAwsSagemakerNotebookInstanceLifeCycleConfiguration(), "aws_sagemaker_notebook_instance": resourceAwsSagemakerNotebookInstance(), "aws_sagemaker_user_profile": resourceAwsSagemakerUserProfile(), diff --git a/aws/resource_aws_sagemaker_model_package_group.go b/aws/resource_aws_sagemaker_model_package_group.go new file mode 100644 index 00000000000..1345a36ac39 --- /dev/null +++ b/aws/resource_aws_sagemaker_model_package_group.go @@ -0,0 +1,151 @@ +package aws + +import ( + "fmt" + "log" + "regexp" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/sagemaker" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sagemaker/finder" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sagemaker/waiter" +) + +func resourceAwsSagemakerModelPackageGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsSagemakerModelPackageGroupCreate, + Read: resourceAwsSagemakerModelPackageGroupRead, + Update: resourceAwsSagemakerModelPackageGroupUpdate, + Delete: resourceAwsSagemakerModelPackageGroupDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "model_package_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 63), + validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9](-*[a-zA-Z0-9]){0,62}$`), + "Valid characters are a-z, A-Z, 0-9, and - (hyphen)."), + ), + }, + "model_package_group_description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 1024), + }, + "tags": tagsSchema(), + }, + } +} + +func resourceAwsSagemakerModelPackageGroupCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).sagemakerconn + + name := d.Get("model_package_group_name").(string) + input := &sagemaker.CreateModelPackageGroupInput{ + ModelPackageGroupName: aws.String(name), + } + + if v, ok := d.GetOk("model_package_group_description"); ok { + input.ModelPackageGroupDescription = aws.String(v.(string)) + } + + if v, ok := d.GetOk("tags"); ok { + input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().SagemakerTags() + } + + _, err := conn.CreateModelPackageGroup(input) + if err != nil { + return fmt.Errorf("error creating Sagemaker Model Package Group %s: %w", name, err) + } + + d.SetId(name) + + if _, err := waiter.ModelPackageGroupCompleted(conn, d.Id()); err != nil { + return fmt.Errorf("error waiting for Sagemaker Model Package Group (%s) to be created: %w", d.Id(), err) + } + + return resourceAwsSagemakerModelPackageGroupRead(d, meta) +} + +func resourceAwsSagemakerModelPackageGroupRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).sagemakerconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + mpg, err := finder.ModelPackageGroupByName(conn, d.Id()) + if err != nil { + if isAWSErr(err, "ValidationException", "does not exist") { + d.SetId("") + log.Printf("[WARN] Unable to find Sagemaker Model Package Group (%s); removing from state", d.Id()) + return nil + } + return fmt.Errorf("error reading Sagemaker Model Package Group (%s): %w", d.Id(), err) + + } + + arn := aws.StringValue(mpg.ModelPackageGroupArn) + d.Set("model_package_group_name", mpg.ModelPackageGroupName) + d.Set("arn", arn) + d.Set("model_package_group_description", mpg.ModelPackageGroupDescription) + + tags, err := keyvaluetags.SagemakerListTags(conn, arn) + + if err != nil { + return fmt.Errorf("error listing tags for Sagemaker Model Package Group (%s): %w", d.Id(), err) + } + + if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + return nil +} + +func resourceAwsSagemakerModelPackageGroupUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).sagemakerconn + + if d.HasChange("tags") { + o, n := d.GetChange("tags") + + if err := keyvaluetags.SagemakerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return fmt.Errorf("error updating Sagemaker Model Package Group (%s) tags: %s", d.Id(), err) + } + } + + return resourceAwsSagemakerModelPackageGroupRead(d, meta) +} + +func resourceAwsSagemakerModelPackageGroupDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).sagemakerconn + + input := &sagemaker.DeleteModelPackageGroupInput{ + ModelPackageGroupName: aws.String(d.Id()), + } + + if _, err := conn.DeleteModelPackageGroup(input); err != nil { + if isAWSErr(err, "ValidationException", "does not exist") { + return nil + } + return fmt.Errorf("error deleting Sagemaker Model Package Group (%s): %w", d.Id(), err) + } + + if _, err := waiter.ModelPackageGroupDeleted(conn, d.Id()); err != nil { + if isAWSErr(err, "ValidationException", "does not exist") { + return nil + } + return fmt.Errorf("error waiting for Sagemaker Model Package Group (%s) to delete: %w", d.Id(), err) + } + + return nil +} diff --git a/aws/resource_aws_sagemaker_model_package_group_test.go b/aws/resource_aws_sagemaker_model_package_group_test.go new file mode 100644 index 00000000000..8e482f52320 --- /dev/null +++ b/aws/resource_aws_sagemaker_model_package_group_test.go @@ -0,0 +1,264 @@ +package aws + +import ( + "fmt" + "log" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/sagemaker" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sagemaker/finder" +) + +func init() { + resource.AddTestSweepers("aws_sagemaker_model_package_group", &resource.Sweeper{ + Name: "aws_sagemaker_model_package_group", + F: testSweepSagemakerModelPackageGroups, + }) +} + +func testSweepSagemakerModelPackageGroups(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*AWSClient).sagemakerconn + + err = conn.ListModelPackageGroupsPages(&sagemaker.ListModelPackageGroupsInput{}, func(page *sagemaker.ListModelPackageGroupsOutput, lastPage bool) bool { + for _, ModelPackageGroup := range page.ModelPackageGroupSummaryList { + name := aws.StringValue(ModelPackageGroup.ModelPackageGroupName) + + input := &sagemaker.DeleteModelPackageGroupInput{ + ModelPackageGroupName: ModelPackageGroup.ModelPackageGroupName, + } + + log.Printf("[INFO] Deleting SageMaker Model Package Group: %s", name) + if _, err := conn.DeleteModelPackageGroup(input); err != nil { + log.Printf("[ERROR] Error deleting SageMaker Model Package Group (%s): %s", name, err) + continue + } + } + + return !lastPage + }) + + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping SageMaker Model Package Group sweep for %s: %s", region, err) + return nil + } + + if err != nil { + return fmt.Errorf("Error retrieving SageMaker Model Package Groups: %w", err) + } + + return nil +} + +func TestAccAWSSagemakerModelPackageGroup_basic(t *testing.T) { + var mpg sagemaker.DescribeModelPackageGroupOutput + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_sagemaker_model_package_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSagemakerModelPackageGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSagemakerModelPackageGroupBasicConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerModelPackageGroupExists(resourceName, &mpg), + resource.TestCheckResourceAttr(resourceName, "model_package_group_name", rName), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "sagemaker", fmt.Sprintf("model-package-group/%s", rName)), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSSagemakerModelPackageGroup_description(t *testing.T) { + var mpg sagemaker.DescribeModelPackageGroupOutput + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_sagemaker_model_package_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSagemakerModelPackageGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSagemakerModelPackageGroupDescription(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerModelPackageGroupExists(resourceName, &mpg), + resource.TestCheckResourceAttr(resourceName, "model_package_group_description", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSSagemakerModelPackageGroup_tags(t *testing.T) { + var mpg sagemaker.DescribeModelPackageGroupOutput + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_sagemaker_model_package_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSagemakerModelPackageGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSagemakerModelPackageGroupConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerModelPackageGroupExists(resourceName, &mpg), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSSagemakerModelPackageGroupConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerModelPackageGroupExists(resourceName, &mpg), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccAWSSagemakerModelPackageGroupConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerModelPackageGroupExists(resourceName, &mpg), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func TestAccAWSSagemakerModelPackageGroup_disappears(t *testing.T) { + var mpg sagemaker.DescribeModelPackageGroupOutput + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_sagemaker_model_package_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSagemakerModelPackageGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSagemakerModelPackageGroupBasicConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerModelPackageGroupExists(resourceName, &mpg), + testAccCheckResourceDisappears(testAccProvider, resourceAwsSagemakerModelPackageGroup(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckAWSSagemakerModelPackageGroupDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).sagemakerconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_sagemaker_model_package_group" { + continue + } + + ModelPackageGroup, err := finder.ModelPackageGroupByName(conn, rs.Primary.ID) + if err != nil { + return nil + } + + if aws.StringValue(ModelPackageGroup.ModelPackageGroupName) == rs.Primary.ID { + return fmt.Errorf("sagemaker Model Package Group %q still exists", rs.Primary.ID) + } + } + + return nil +} + +func testAccCheckAWSSagemakerModelPackageGroupExists(n string, mpg *sagemaker.DescribeModelPackageGroupOutput) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No sagmaker Model Package Group ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).sagemakerconn + resp, err := finder.ModelPackageGroupByName(conn, rs.Primary.ID) + if err != nil { + return err + } + + *mpg = *resp + + return nil + } +} + +func testAccAWSSagemakerModelPackageGroupBasicConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_sagemaker_model_package_group" "test" { + model_package_group_name = %[1]q +} +`, rName) +} + +func testAccAWSSagemakerModelPackageGroupDescription(rName string) string { + return fmt.Sprintf(` +resource "aws_sagemaker_model_package_group" "test" { + model_package_group_name = %[1]q + model_package_group_description = %[1]q +} +`, rName) +} + +func testAccAWSSagemakerModelPackageGroupConfigTags1(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_sagemaker_model_package_group" "test" { + model_package_group_name = %[1]q + + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1) +} + +func testAccAWSSagemakerModelPackageGroupConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_sagemaker_model_package_group" "test" { + model_package_group_name = %[1]q + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +} From 0892a7089b71cbcaf6c04823807a8064e7100cc3 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sat, 30 Jan 2021 13:39:27 +0200 Subject: [PATCH 2/6] add force new to desc --- aws/resource_aws_sagemaker_model_package_group.go | 1 + 1 file changed, 1 insertion(+) diff --git a/aws/resource_aws_sagemaker_model_package_group.go b/aws/resource_aws_sagemaker_model_package_group.go index 1345a36ac39..19d36cd6045 100644 --- a/aws/resource_aws_sagemaker_model_package_group.go +++ b/aws/resource_aws_sagemaker_model_package_group.go @@ -42,6 +42,7 @@ func resourceAwsSagemakerModelPackageGroup() *schema.Resource { "model_package_group_description": { Type: schema.TypeString, Optional: true, + ForceNew: true, ValidateFunc: validation.StringLenBetween(1, 1024), }, "tags": tagsSchema(), From 476e9c811e7c855c1e334f50d39b481854c0f923 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sat, 30 Jan 2021 13:42:08 +0200 Subject: [PATCH 3/6] docs --- ...agemaker_model_package_group.html.markdown | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 website/docs/r/sagemaker_model_package_group.html.markdown diff --git a/website/docs/r/sagemaker_model_package_group.html.markdown b/website/docs/r/sagemaker_model_package_group.html.markdown new file mode 100644 index 00000000000..d5346652e3e --- /dev/null +++ b/website/docs/r/sagemaker_model_package_group.html.markdown @@ -0,0 +1,44 @@ +--- +subcategory: "Sagemaker" +layout: "aws" +page_title: "AWS: aws_sagemaker_model_package_group" +description: |- + Provides a Sagemaker Model Package Group resource. +--- + +# Resource: aws_sagemaker_model_package_group + +Provides a Sagemaker Model Package Group resource. + +## Example Usage + +### Basic usage + +```hcl +resource "aws_sagemaker_model_package_group" "example" { + model_package_group_name = "example" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `model_package_group_name` - (Required) The name of the model group. +* `model_package_group_description` - (Optional) A description for the model group. +* `tags` - (Optional) A map of tags to assign to the resource. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The name of the Model Package Group. +* `arn` - The Amazon Resource Name (ARN) assigned by AWS to this Model Package Group. + +## Import + +Sagemaker Code Model Package Groups can be imported using the `name`, e.g. + +``` +$ terraform import aws_sagemaker_model_package_group.test_model_package_group my-code-repo +``` From 64d14ed23c232c6d2bdb2fb8da0e744ee969c8a3 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sat, 30 Jan 2021 13:45:37 +0200 Subject: [PATCH 4/6] changelog --- .changelog/17366.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/17366.txt diff --git a/.changelog/17366.txt b/.changelog/17366.txt new file mode 100644 index 00000000000..340b0a5cc4a --- /dev/null +++ b/.changelog/17366.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_sagemaker_model_package_group +``` \ No newline at end of file From 1d2abb955c5647b8f709b47e55621c5145982986 Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Sun, 31 Jan 2021 10:25:40 +0200 Subject: [PATCH 5/6] copy-pasta --- aws/internal/service/sagemaker/finder/finder.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/internal/service/sagemaker/finder/finder.go b/aws/internal/service/sagemaker/finder/finder.go index 3236aa4544d..280f46778b4 100644 --- a/aws/internal/service/sagemaker/finder/finder.go +++ b/aws/internal/service/sagemaker/finder/finder.go @@ -24,8 +24,8 @@ func CodeRepositoryByName(conn *sagemaker.SageMaker, name string) (*sagemaker.De return output, nil } -// ModelPackageGroupByName returns the code repository corresponding to the specified name. -// Returns nil if no code repository is found. +// ModelPackageGroupByName returns the Model Package Group corresponding to the specified name. +// Returns nil if no Model Package Group is found. func ModelPackageGroupByName(conn *sagemaker.SageMaker, name string) (*sagemaker.DescribeModelPackageGroupOutput, error) { input := &sagemaker.DescribeModelPackageGroupInput{ ModelPackageGroupName: aws.String(name), From 890aa38d28714f211e9ecab57ae795465edb48f5 Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Tue, 2 Feb 2021 08:58:26 +0200 Subject: [PATCH 6/6] Apply suggestions from code review Co-authored-by: Kit Ewbank --- aws/resource_aws_sagemaker_model_package_group.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_sagemaker_model_package_group.go b/aws/resource_aws_sagemaker_model_package_group.go index 19d36cd6045..06a655df984 100644 --- a/aws/resource_aws_sagemaker_model_package_group.go +++ b/aws/resource_aws_sagemaker_model_package_group.go @@ -68,7 +68,7 @@ func resourceAwsSagemakerModelPackageGroupCreate(d *schema.ResourceData, meta in _, err := conn.CreateModelPackageGroup(input) if err != nil { - return fmt.Errorf("error creating Sagemaker Model Package Group %s: %w", name, err) + return fmt.Errorf("error creating SageMaker Model Package Group %s: %w", name, err) } d.SetId(name) @@ -91,7 +91,7 @@ func resourceAwsSagemakerModelPackageGroupRead(d *schema.ResourceData, meta inte log.Printf("[WARN] Unable to find Sagemaker Model Package Group (%s); removing from state", d.Id()) return nil } - return fmt.Errorf("error reading Sagemaker Model Package Group (%s): %w", d.Id(), err) + return fmt.Errorf("error reading SageMaker Model Package Group (%s): %w", d.Id(), err) } @@ -103,7 +103,7 @@ func resourceAwsSagemakerModelPackageGroupRead(d *schema.ResourceData, meta inte tags, err := keyvaluetags.SagemakerListTags(conn, arn) if err != nil { - return fmt.Errorf("error listing tags for Sagemaker Model Package Group (%s): %w", d.Id(), err) + return fmt.Errorf("error listing tags for SageMaker Model Package Group (%s): %w", d.Id(), err) } if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { @@ -120,7 +120,7 @@ func resourceAwsSagemakerModelPackageGroupUpdate(d *schema.ResourceData, meta in o, n := d.GetChange("tags") if err := keyvaluetags.SagemakerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { - return fmt.Errorf("error updating Sagemaker Model Package Group (%s) tags: %s", d.Id(), err) + return fmt.Errorf("error updating SageMaker Model Package Group (%s) tags: %s", d.Id(), err) } } @@ -138,14 +138,14 @@ func resourceAwsSagemakerModelPackageGroupDelete(d *schema.ResourceData, meta in if isAWSErr(err, "ValidationException", "does not exist") { return nil } - return fmt.Errorf("error deleting Sagemaker Model Package Group (%s): %w", d.Id(), err) + return fmt.Errorf("error deleting SageMaker Model Package Group (%s): %w", d.Id(), err) } if _, err := waiter.ModelPackageGroupDeleted(conn, d.Id()); err != nil { if isAWSErr(err, "ValidationException", "does not exist") { return nil } - return fmt.Errorf("error waiting for Sagemaker Model Package Group (%s) to delete: %w", d.Id(), err) + return fmt.Errorf("error waiting for SageMaker Model Package Group (%s) to delete: %w", d.Id(), err) } return nil