From 1fd13e7c71579591fe17385f97dc4af2efa7e70e Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sun, 25 Oct 2020 11:34:52 +0200 Subject: [PATCH 1/2] add support for `additional_code_repositories` --- ...esource_aws_sagemaker_notebook_instance.go | 22 ++++++ ...ce_aws_sagemaker_notebook_instance_test.go | 74 +++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/aws/resource_aws_sagemaker_notebook_instance.go b/aws/resource_aws_sagemaker_notebook_instance.go index b5251f8fa14c..0a4fd7c3cf49 100644 --- a/aws/resource_aws_sagemaker_notebook_instance.go +++ b/aws/resource_aws_sagemaker_notebook_instance.go @@ -55,6 +55,11 @@ func resourceAwsSagemakerNotebookInstance() *schema.Resource { Required: true, ValidateFunc: validation.StringInSlice(sagemaker.InstanceType_Values(), false), }, + "additional_code_repositories": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "volume_size": { Type: schema.TypeInt, @@ -165,6 +170,10 @@ func resourceAwsSagemakerNotebookInstanceCreate(d *schema.ResourceData, meta int createOpts.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().SagemakerTags() } + if v, ok := d.GetOk("additional_code_repositories"); ok && v.(*schema.Set).Len() > 0 { + createOpts.AdditionalCodeRepositories = expandStringSet(v.(*schema.Set)) + } + log.Printf("[DEBUG] sagemaker notebook instance create config: %#v", *createOpts) _, err := conn.CreateNotebookInstance(createOpts) if err != nil { @@ -251,6 +260,10 @@ func resourceAwsSagemakerNotebookInstanceRead(d *schema.ResourceData, meta inter return fmt.Errorf("error setting network_interface_id for sagemaker notebook instance (%s): %w", d.Id(), err) } + if err := d.Set("additional_code_repositories", flattenStringSet(notebookInstance.AdditionalCodeRepositories)); err != nil { + return fmt.Errorf("error setting additional_code_repositories for sagemaker notebook instance (%s): %s", d.Id(), err) + } + tags, err := keyvaluetags.SagemakerListTags(conn, aws.StringValue(notebookInstance.NotebookInstanceArn)) if err != nil { @@ -319,6 +332,15 @@ func resourceAwsSagemakerNotebookInstanceUpdate(d *schema.ResourceData, meta int hasChanged = true } + if d.HasChange("additional_code_repositories") { + if v, ok := d.GetOk("additional_code_repositories"); ok { + updateOpts.AdditionalCodeRepositories = expandStringSet(v.(*schema.Set)) + } else { + updateOpts.DisassociateAdditionalCodeRepositories = aws.Bool(true) + } + hasChanged = true + } + if hasChanged { // Stop notebook diff --git a/aws/resource_aws_sagemaker_notebook_instance_test.go b/aws/resource_aws_sagemaker_notebook_instance_test.go index deee44ba8ae7..a7bf3fd9ca8b 100644 --- a/aws/resource_aws_sagemaker_notebook_instance_test.go +++ b/aws/resource_aws_sagemaker_notebook_instance_test.go @@ -13,6 +13,7 @@ import ( "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/waiter" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfawsresource" ) func init() { @@ -94,6 +95,7 @@ func TestAccAWSSagemakerNotebookInstance_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "root_access", "Enabled"), resource.TestCheckResourceAttr(resourceName, "volume_size", "5"), resource.TestCheckResourceAttr(resourceName, "default_code_repository", ""), + resource.TestCheckResourceAttr(resourceName, "additional_code_repositories.#", "0"), resource.TestCheckResourceAttr(resourceName, "security_groups.#", "0"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "url"), @@ -497,6 +499,56 @@ func TestAccAWSSagemakerNotebookInstance_default_code_repository(t *testing.T) { }) } +func TestAccAWSSagemakerNotebookInstance_additional_code_repositories(t *testing.T) { + var notebook sagemaker.DescribeNotebookInstanceOutput + rName := acctest.RandomWithPrefix("tf-acc-test") + var resourceName = "aws_sagemaker_notebook_instance.test" + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSagemakerNotebookInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSagemakerNotebookInstanceConfigAdditionalCodeRepository1(rName, "https://github.com/terraform-providers/terraform-provider-aws.git"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerNotebookInstanceExists(resourceName, ¬ebook), + resource.TestCheckResourceAttr(resourceName, "additional_code_repositories.#", "1"), + tfawsresource.TestCheckTypeSetElemAttr(resourceName, "additional_code_repositories.*", "https://github.com/terraform-providers/terraform-provider-aws.git"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSSagemakerNotebookInstanceBasicConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerNotebookInstanceExists(resourceName, ¬ebook), + resource.TestCheckResourceAttr(resourceName, "additional_code_repositories.#", "0"), + ), + }, + { + Config: testAccAWSSagemakerNotebookInstanceConfigAdditionalCodeRepository2(rName, "https://github.com/terraform-providers/terraform-provider-aws.git", "https://github.com/hashicorp/terraform.git"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerNotebookInstanceExists(resourceName, ¬ebook), + resource.TestCheckResourceAttr(resourceName, "additional_code_repositories.#", "2"), + tfawsresource.TestCheckTypeSetElemAttr(resourceName, "additional_code_repositories.*", "https://github.com/terraform-providers/terraform-provider-aws.git"), + tfawsresource.TestCheckTypeSetElemAttr(resourceName, "additional_code_repositories.*", "https://github.com/hashicorp/terraform.git"), + ), + }, + { + Config: testAccAWSSagemakerNotebookInstanceConfigAdditionalCodeRepository1(rName, "https://github.com/terraform-providers/terraform-provider-aws.git"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSagemakerNotebookInstanceExists(resourceName, ¬ebook), + resource.TestCheckResourceAttr(resourceName, "additional_code_repositories.#", "1"), + tfawsresource.TestCheckTypeSetElemAttr(resourceName, "additional_code_repositories.*", "https://github.com/terraform-providers/terraform-provider-aws.git"), + ), + }, + }, + }) +} + func testAccAWSSagemakerNotebookInstanceBaseConfig(rName string) string { return fmt.Sprintf(` resource "aws_iam_role" "test" { @@ -654,6 +706,28 @@ resource "aws_sagemaker_notebook_instance" "test" { `, rName, defaultCodeRepository) } +func testAccAWSSagemakerNotebookInstanceConfigAdditionalCodeRepository1(rName, repo1 string) string { + return testAccAWSSagemakerNotebookInstanceBaseConfig(rName) + fmt.Sprintf(` +resource "aws_sagemaker_notebook_instance" "test" { + name = %[1]q + role_arn = aws_iam_role.test.arn + instance_type = "ml.t2.medium" + additional_code_repositories = ["%[2]s"] +} +`, rName, repo1) +} + +func testAccAWSSagemakerNotebookInstanceConfigAdditionalCodeRepository2(rName, repo1, repo2 string) string { + return testAccAWSSagemakerNotebookInstanceBaseConfig(rName) + fmt.Sprintf(` +resource "aws_sagemaker_notebook_instance" "test" { + name = %[1]q + role_arn = aws_iam_role.test.arn + instance_type = "ml.t2.medium" + additional_code_repositories = ["%[2]s", "%[3]s"] +} +`, rName, repo1, repo2) +} + func testAccAWSSagemakerNotebookInstanceKMSConfig(rName string) string { return testAccAWSSagemakerNotebookInstanceBaseConfig(rName) + fmt.Sprintf(` resource "aws_kms_key" "test" { From 92a7f27f1ecfb147f883d5c4d6d264f5aecc4263 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sun, 25 Oct 2020 11:37:55 +0200 Subject: [PATCH 2/2] add docs + set max items --- aws/resource_aws_sagemaker_notebook_instance.go | 1 + website/docs/r/sagemaker_notebook_instance.html.markdown | 2 ++ 2 files changed, 3 insertions(+) diff --git a/aws/resource_aws_sagemaker_notebook_instance.go b/aws/resource_aws_sagemaker_notebook_instance.go index 0a4fd7c3cf49..1b0e34863178 100644 --- a/aws/resource_aws_sagemaker_notebook_instance.go +++ b/aws/resource_aws_sagemaker_notebook_instance.go @@ -58,6 +58,7 @@ func resourceAwsSagemakerNotebookInstance() *schema.Resource { "additional_code_repositories": { Type: schema.TypeSet, Optional: true, + MaxItems: 3, Elem: &schema.Schema{Type: schema.TypeString}, }, diff --git a/website/docs/r/sagemaker_notebook_instance.html.markdown b/website/docs/r/sagemaker_notebook_instance.html.markdown index a4a9698f5b85..e89d4c359386 100644 --- a/website/docs/r/sagemaker_notebook_instance.html.markdown +++ b/website/docs/r/sagemaker_notebook_instance.html.markdown @@ -41,6 +41,8 @@ The following arguments are supported: * `root_access` - (Optional) Whether root access is `Enabled` or `Disabled` for users of the notebook instance. The default value is `Enabled`. * `direct_internet_access` - (Optional) Set to `Disabled` to disable internet access to notebook. Requires `security_groups` and `subnet_id` to be set. Supported values: `Enabled` (Default) or `Disabled`. If set to `Disabled`, the notebook instance will be able to access resources only in your VPC, and will not be able to connect to Amazon SageMaker training and endpoint services unless your configure a NAT Gateway in your VPC. * `default_code_repository` - (Optional) The Git repository associated with the notebook instance as its default code repository +* `additional_code_repositories` - (Optional) An array of up to three Git repositories to associate with the notebook instance. + These can be either the names of Git repositories stored as resources in your account, or the URL of Git repositories in [AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/welcome.html) or in any other Git repository. These repositories are cloned at the same level as the default repository of your notebook instance. * `tags` - (Optional) A map of tags to assign to the resource. ## Attributes Reference