diff --git a/.changelog/21037.txt b/.changelog/21037.txt new file mode 100644 index 00000000000..0e622959dd4 --- /dev/null +++ b/.changelog/21037.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_sagemaker_app_image_config: Add tagging support. +``` \ No newline at end of file diff --git a/aws/resource_aws_sagemaker_app_image_config.go b/aws/resource_aws_sagemaker_app_image_config.go index b6fb91fccf2..b7dc8812d6e 100644 --- a/aws/resource_aws_sagemaker_app_image_config.go +++ b/aws/resource_aws_sagemaker_app_image_config.go @@ -9,6 +9,7 @@ import ( "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" ) @@ -94,18 +95,27 @@ func resourceAwsSagemakerAppImageConfig() *schema.Resource { }, }, }, + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + CustomizeDiff: SetTagsDiff, } } func resourceAwsSagemakerAppImageConfigCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).sagemakerconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) name := d.Get("app_image_config_name").(string) input := &sagemaker.CreateAppImageConfigInput{ AppImageConfigName: aws.String(name), } + if len(tags) > 0 { + input.Tags = tags.IgnoreAws().SagemakerTags() + } + if v, ok := d.GetOk("kernel_gateway_image_config"); ok && len(v.([]interface{})) > 0 { input.KernelGatewayImageConfig = expandSagemakerAppImageConfigKernelGatewayImageConfig(v.([]interface{})) } @@ -122,6 +132,8 @@ func resourceAwsSagemakerAppImageConfigCreate(d *schema.ResourceData, meta inter func resourceAwsSagemakerAppImageConfigRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).sagemakerconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig image, err := finder.AppImageConfigByName(conn, d.Id()) if err != nil { @@ -142,12 +154,37 @@ func resourceAwsSagemakerAppImageConfigRead(d *schema.ResourceData, meta interfa return fmt.Errorf("error setting kernel_gateway_image_config: %w", err) } + tags, err := keyvaluetags.SagemakerListTags(conn, arn) + + if err != nil { + return fmt.Errorf("error listing tags for SageMaker App Image Config (%s): %w", d.Id(), err) + } + + tags = tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + return nil } func resourceAwsSagemakerAppImageConfigUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).sagemakerconn + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") + + if err := keyvaluetags.SagemakerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return fmt.Errorf("error updating SageMaker App Image Config (%s) tags: %w", d.Id(), err) + } + } + if d.HasChange("kernel_gateway_image_config") { input := &sagemaker.UpdateAppImageConfigInput{ diff --git a/aws/resource_aws_sagemaker_app_image_config_test.go b/aws/resource_aws_sagemaker_app_image_config_test.go index ba0d8133887..2453a0974a3 100644 --- a/aws/resource_aws_sagemaker_app_image_config_test.go +++ b/aws/resource_aws_sagemaker_app_image_config_test.go @@ -190,6 +190,51 @@ func TestAccAWSSagemakerAppImageConfig_kernelGatewayImageConfig_fileSystemConfig }) } +func TestAccAWSSagemakerAppImageConfig_tags(t *testing.T) { + var app sagemaker.DescribeAppImageConfigOutput + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_sagemaker_app_image_config.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, sagemaker.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSagemakerAppDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSagemakerAppConfigImageConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerAppImageConfigExists(resourceName, &app), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSSagemakerAppConfigImageConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerAppImageConfigExists(resourceName, &app), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccAWSSagemakerAppConfigImageConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerAppImageConfigExists(resourceName, &app), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + func TestAccAWSSagemakerAppImageConfig_disappears(t *testing.T) { var config sagemaker.DescribeAppImageConfigOutput rName := acctest.RandomWithPrefix("tf-acc-test") @@ -334,3 +379,28 @@ resource "aws_sagemaker_app_image_config" "test" { } `, rName) } + +func testAccAWSSagemakerAppConfigImageConfigTags1(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_sagemaker_app_image_config" "test" { + app_image_config_name = %[1]q + + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1) +} + +func testAccAWSSagemakerAppConfigImageConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_sagemaker_app_image_config" "test" { + app_image_config_name = %[1]q + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +} diff --git a/website/docs/r/sagemaker_app_image_config.html.markdown b/website/docs/r/sagemaker_app_image_config.html.markdown index a90519d1af0..3cfbadbfa13 100644 --- a/website/docs/r/sagemaker_app_image_config.html.markdown +++ b/website/docs/r/sagemaker_app_image_config.html.markdown @@ -48,6 +48,7 @@ The following arguments are supported: * `app_image_config_name` - (Required) The name of the App Image Config. * `kernel_gateway_image_config` - (Optional) The configuration for the file system and kernels in a SageMaker image running as a KernelGateway app. See [Kernel Gateway Image Config](#kernel-gateway-image-config) details below. +* `tags` - (Optional) A map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ### Kernel Gateway Image Config @@ -73,6 +74,7 @@ In addition to all arguments above, the following attributes are exported: * `id` - The name of the App Image Config. * `arn` - The Amazon Resource Name (ARN) assigned by AWS to this App Image Config. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import