From 69810af532bcc043c884aa8f3851a7983c422277 Mon Sep 17 00:00:00 2001 From: Andrew Babichev Date: Tue, 17 Nov 2020 15:59:21 +0200 Subject: [PATCH] aws_workspaces_directory: Assign IP group --- aws/resource_aws_workspaces_directory.go | 42 ++++++++++ aws/resource_aws_workspaces_directory_test.go | 80 +++++++++++++++++++ aws/resource_aws_workspaces_ip_group.go | 42 +++++++++- .../docs/r/workspaces_directory.html.markdown | 19 ++++- 4 files changed, 179 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_workspaces_directory.go b/aws/resource_aws_workspaces_directory.go index a9d148e0c4a..f3aaaeeb696 100644 --- a/aws/resource_aws_workspaces_directory.go +++ b/aws/resource_aws_workspaces_directory.go @@ -55,6 +55,7 @@ func resourceAwsWorkspacesDirectory() *schema.Resource { Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeString}, Computed: true, + Optional: true, }, "registration_code": { Type: schema.TypeString, @@ -200,6 +201,19 @@ func resourceAwsWorkspacesDirectoryCreate(d *schema.ResourceData, meta interface log.Printf("[DEBUG] WorkSpaces Directory %q creation properties are set", directoryId) } + if v, ok := d.GetOk("ip_group_ids"); ok && v.(*schema.Set).Len() > 0 { + ipGroupIds := v.(*schema.Set) + log.Printf("[DEBUG] Associate WorkSpaces Directory %q with IP Groups %s...", directoryId, ipGroupIds.List()) + _, err := conn.AssociateIpGroups(&workspaces.AssociateIpGroupsInput{ + DirectoryId: aws.String(directoryId), + GroupIds: expandStringSet(ipGroupIds), + }) + if err != nil { + return fmt.Errorf("error asassociating ip groups: %s", err) + } + log.Printf("[DEBUG] WorkSpaces Directory %q IP Groups are set", directoryId) + } + return resourceAwsWorkspacesDirectoryRead(d, meta) } @@ -288,6 +302,34 @@ func resourceAwsWorkspacesDirectoryUpdate(d *schema.ResourceData, meta interface log.Printf("[DEBUG] WorkSpaces Directory %q creation properties are set", d.Id()) } + if d.HasChange("ip_group_ids") { + o, n := d.GetChange("ip_group_ids") + old := o.(*schema.Set) + new := n.(*schema.Set) + added := new.Difference(old) + removed := old.Difference(new) + + log.Printf("[DEBUG] Associate IP Groups %s from WorkSpaces Directory %q...", added.GoString(), d.Id()) + _, err := conn.AssociateIpGroups(&workspaces.AssociateIpGroupsInput{ + DirectoryId: aws.String(d.Id()), + GroupIds: expandStringSet(added), + }) + if err != nil { + return fmt.Errorf("error asassociating ip groups: %s", err) + } + + log.Printf("[DEBUG] Disassociate IP Groups %s from WorkSpaces Directory %q...", removed.GoString(), d.Id()) + _, err = conn.DisassociateIpGroups(&workspaces.DisassociateIpGroupsInput{ + DirectoryId: aws.String(d.Id()), + GroupIds: expandStringSet(removed), + }) + if err != nil { + return fmt.Errorf("error disasassociating ip groups: %s", err) + } + + log.Printf("[DEBUG] WorkSpaces Directory %q IP Groups are set", d.Id()) + } + if d.HasChange("tags") { o, n := d.GetChange("tags") if err := keyvaluetags.WorkspacesUpdateTags(conn, d.Id(), o, n); err != nil { diff --git a/aws/resource_aws_workspaces_directory_test.go b/aws/resource_aws_workspaces_directory_test.go index 3dffc6b8b00..9c18ea9f803 100644 --- a/aws/resource_aws_workspaces_directory_test.go +++ b/aws/resource_aws_workspaces_directory_test.go @@ -283,6 +283,45 @@ func TestAccAwsWorkspacesDirectory_workspaceCreationProperties(t *testing.T) { }) } +func TestAccAwsWorkspacesDirectory_ipGroupIds(t *testing.T) { + var v workspaces.WorkspaceDirectory + rName := acctest.RandString(8) + + resourceName := "aws_workspaces_directory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckHasIAMRole(t, "workspaces_DefaultRole") }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsWorkspacesDirectoryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccWorkspacesDirectoryConfig_ipGroupIds_create(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsWorkspacesDirectoryExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "ip_group_ids.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccWorkspacesDirectoryConfig_ipGroupIds_update(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsWorkspacesDirectoryExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "ip_group_ids.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccPreCheckHasIAMRole(t *testing.T, roleName string) { conn := testAccProvider.Meta().(*AWSClient).iamconn @@ -618,3 +657,44 @@ resource "aws_workspaces_directory" "main" { } `, rName)) } + +func testAccWorkspacesDirectoryConfig_ipGroupIds_create(rName string) string { + return composeConfig( + testAccAwsWorkspacesDirectoryConfig_Prerequisites(rName), + fmt.Sprintf(` +resource "aws_workspaces_ip_group" "test_alpha" { + name = "%[1]s-alpha" +} + +resource "aws_workspaces_directory" "test" { + directory_id = aws_directory_service_directory.main.id + + ip_group_ids = [ + aws_workspaces_ip_group.test_alpha.id + ] +} +`, rName)) +} + +func testAccWorkspacesDirectoryConfig_ipGroupIds_update(rName string) string { + return composeConfig( + testAccAwsWorkspacesDirectoryConfig_Prerequisites(rName), + fmt.Sprintf(` +resource "aws_workspaces_ip_group" "test_beta" { + name = "%[1]s-beta" +} + +resource "aws_workspaces_ip_group" "test_gamma" { + name = "%[1]s-gamma" +} + +resource "aws_workspaces_directory" "test" { + directory_id = aws_directory_service_directory.main.id + + ip_group_ids = [ + aws_workspaces_ip_group.test_beta.id, + aws_workspaces_ip_group.test_gamma.id + ] +} +`, rName)) +} diff --git a/aws/resource_aws_workspaces_ip_group.go b/aws/resource_aws_workspaces_ip_group.go index 841f7d12dd9..b21914cf713 100644 --- a/aws/resource_aws_workspaces_ip_group.go +++ b/aws/resource_aws_workspaces_ip_group.go @@ -148,13 +148,49 @@ func resourceAwsWorkspacesIpGroupUpdate(d *schema.ResourceData, meta interface{} func resourceAwsWorkspacesIpGroupDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).workspacesconn - log.Printf("[INFO] Deleting Workspaces IP Group") - _, err := conn.DeleteIpGroup(&workspaces.DeleteIpGroupInput{ + var directoryID *string + + log.Printf("[DEBUG] Finding directory associated with Workspaces IP Group %q", d.Id()) + err := conn.DescribeWorkspaceDirectoriesPages(nil, + func(page *workspaces.DescribeWorkspaceDirectoriesOutput, lastPage bool) bool { + for _, dir := range page.Directories { + for _, ipg := range dir.IpGroupIds { + if aws.StringValue(ipg) == d.Id() { + directoryID = dir.DirectoryId + return true + } + } + } + return !lastPage + }, + ) + if err != nil { + return fmt.Errorf("error describing Workspaces IP Groups: %s", err) + } + + if directoryID == nil { + log.Printf("[DEBUG] Workspaces IP Group %q is not associated with any Directory", d.Id()) + } else { + log.Printf("[DEBUG] Workspaces IP Group %q is associated with Directory %q", d.Id(), aws.StringValue(directoryID)) + log.Printf("[INFO] Disassociating Workspaces IP Group %q from Directory %q", d.Id(), aws.StringValue(directoryID)) + _, err = conn.DisassociateIpGroups(&workspaces.DisassociateIpGroupsInput{ + DirectoryId: directoryID, + GroupIds: aws.StringSlice([]string{d.Id()}), + }) + if err != nil { + return fmt.Errorf("error disassociating Workspaces IP Group: %s", err) + } + log.Printf("[INFO] Workspaces IP Group %q has been successfully disassociated from Directory %q", d.Id(), aws.StringValue(directoryID)) + } + + log.Printf("[INFO] Deleting Workspaces IP Group %q", d.Id()) + _, err = conn.DeleteIpGroup(&workspaces.DeleteIpGroupInput{ GroupId: aws.String(d.Id()), }) if err != nil { - return fmt.Errorf("Error Deleting Workspaces IP Group: %s", err) + return fmt.Errorf("error deleting Workspaces IP Group: %s", err) } + log.Printf("[INFO] Workspaces IP Group %q has been successfully deleted", d.Id()) return nil } diff --git a/website/docs/r/workspaces_directory.html.markdown b/website/docs/r/workspaces_directory.html.markdown index aa4431be6a6..ea87bec8ff0 100644 --- a/website/docs/r/workspaces_directory.html.markdown +++ b/website/docs/r/workspaces_directory.html.markdown @@ -116,12 +116,29 @@ resource "aws_subnet" "example_d" { } ``` +### IP Groups + +```hcl +resource "aws_workspaces_directory" "example" { + directory_id = aws_directory_service_directory.example.id + + ip_group_ids = [ + aws_workspaces_ip_group.example.id, + ] +} + +resource "aws_workspaces_ip_group" "example" { + name = "example" +} +``` + ## Arguments Reference The following arguments are supported: * `directory_id` - (Required) The directory identifier for registration in WorkSpaces service. -* `subnet_ids` - (Optional) The subnets identifiers where the workspaces are created. +* `subnet_ids` - (Optional) The identifiers of the subnets where the directory resides. +* `ip_group_ids` - The identifiers of the IP access control groups associated with the directory. * `tags` – (Optional) A map of tags assigned to the WorkSpaces directory. * `self_service_permissions` – (Optional) Permissions to enable or disable self-service capabilities. Defined below. * `workspace_creation_properties` – (Optional) Default properties that are used for creating WorkSpaces. Defined below.