diff --git a/.changelog/20054.txt b/.changelog/20054.txt new file mode 100644 index 000000000000..17613fbece00 --- /dev/null +++ b/.changelog/20054.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/fsx_windows_file_system: Add `aliases` argument. +``` diff --git a/aws/fsx.go b/aws/fsx.go index 73afe902a41d..9e4cc968e8a5 100644 --- a/aws/fsx.go +++ b/aws/fsx.go @@ -1,11 +1,13 @@ package aws import ( + "errors" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/fsx" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) func describeFsxFileSystem(conn *fsx.FSx, id string) (*fsx.FileSystem, error) { @@ -48,7 +50,7 @@ func refreshFsxFileSystemLifecycle(conn *fsx.FSx, id string) resource.StateRefre } } -func refreshFsxFileSystemAdministrativeActionsStatusFileSystemUpdate(conn *fsx.FSx, id string) resource.StateRefreshFunc { +func refreshFsxFileSystemAdministrativeActionsStatusFileSystemUpdate(conn *fsx.FSx, id, action string) resource.StateRefreshFunc { return func() (interface{}, string, error) { filesystem, err := describeFsxFileSystem(conn, id) @@ -69,7 +71,7 @@ func refreshFsxFileSystemAdministrativeActionsStatusFileSystemUpdate(conn *fsx.F continue } - if aws.StringValue(administrativeAction.AdministrativeActionType) == fsx.AdministrativeActionTypeFileSystemUpdate { + if aws.StringValue(administrativeAction.AdministrativeActionType) == action { return filesystem, aws.StringValue(administrativeAction.Status), nil } } @@ -87,7 +89,13 @@ func waitForFsxFileSystemCreation(conn *fsx.FSx, id string, timeout time.Duratio Delay: 30 * time.Second, } - _, err := stateConf.WaitForState() + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*fsx.FileSystem); ok { + if output.FailureDetails != nil { + tfresource.SetLastError(err, errors.New(aws.StringValue(output.FailureDetails.Message))) + } + } return err } @@ -101,7 +109,13 @@ func waitForFsxFileSystemDeletion(conn *fsx.FSx, id string, timeout time.Duratio Delay: 30 * time.Second, } - _, err := stateConf.WaitForState() + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*fsx.FileSystem); ok { + if output.FailureDetails != nil { + tfresource.SetLastError(err, errors.New(aws.StringValue(output.FailureDetails.Message))) + } + } return err } @@ -120,7 +134,7 @@ func waitForFsxFileSystemUpdate(conn *fsx.FSx, id string, timeout time.Duration) return err } -func waitForFsxFileSystemUpdateAdministrativeActionsStatusFileSystemUpdate(conn *fsx.FSx, id string, timeout time.Duration) error { +func waitForFsxFileSystemUpdateAdministrativeActionsStatusFileSystemUpdate(conn *fsx.FSx, id, action string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{ fsx.StatusInProgress, @@ -130,7 +144,7 @@ func waitForFsxFileSystemUpdateAdministrativeActionsStatusFileSystemUpdate(conn fsx.StatusCompleted, fsx.StatusUpdatedOptimizing, }, - Refresh: refreshFsxFileSystemAdministrativeActionsStatusFileSystemUpdate(conn, id), + Refresh: refreshFsxFileSystemAdministrativeActionsStatusFileSystemUpdate(conn, id, action), Timeout: timeout, Delay: 30 * time.Second, } diff --git a/aws/internal/service/directoryservice/finder/finder.go b/aws/internal/service/directoryservice/finder/finder.go new file mode 100644 index 000000000000..3ce7a870786b --- /dev/null +++ b/aws/internal/service/directoryservice/finder/finder.go @@ -0,0 +1,48 @@ +package finder + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/directoryservice" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func DirectoryByID(conn *directoryservice.DirectoryService, id string) (*directoryservice.DirectoryDescription, error) { + input := &directoryservice.DescribeDirectoriesInput{ + DirectoryIds: aws.StringSlice([]string{id}), + } + + output, err := conn.DescribeDirectories(input) + + if tfawserr.ErrCodeEquals(err, directoryservice.ErrCodeEntityDoesNotExistException) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + if output == nil || len(output.DirectoryDescriptions) == 0 || output.DirectoryDescriptions[0] == nil { + return nil, &resource.NotFoundError{ + Message: "Empty result", + LastRequest: input, + } + } + + // TODO Check for multiple results. + // TODO https://github.com/hashicorp/terraform-provider-aws/pull/17613. + + directory := output.DirectoryDescriptions[0] + + if stage := aws.StringValue(directory.Stage); stage == directoryservice.DirectoryStageDeleted { + return nil, &resource.NotFoundError{ + Message: stage, + LastRequest: input, + } + } + + return directory, nil +} diff --git a/aws/internal/service/directoryservice/waiter/status.go b/aws/internal/service/directoryservice/waiter/status.go new file mode 100644 index 000000000000..7f6796238b25 --- /dev/null +++ b/aws/internal/service/directoryservice/waiter/status.go @@ -0,0 +1,25 @@ +package waiter + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/directoryservice" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/directoryservice/finder" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" +) + +func DirectoryStage(conn *directoryservice.DirectoryService, id string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := finder.DirectoryByID(conn, id) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, aws.StringValue(output.Stage), nil + } +} diff --git a/aws/internal/service/directoryservice/waiter/waiter.go b/aws/internal/service/directoryservice/waiter/waiter.go new file mode 100644 index 000000000000..47ad07a5606b --- /dev/null +++ b/aws/internal/service/directoryservice/waiter/waiter.go @@ -0,0 +1,54 @@ +package waiter + +import ( + "errors" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/directoryservice" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" +) + +const ( + DirectoryCreatedTimeout = 60 * time.Minute + DirectoryDeletedTimeout = 60 * time.Minute +) + +func DirectoryCreated(conn *directoryservice.DirectoryService, id string) (*directoryservice.DirectoryDescription, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{directoryservice.DirectoryStageRequested, directoryservice.DirectoryStageCreating, directoryservice.DirectoryStageCreated}, + Target: []string{directoryservice.DirectoryStageActive}, + Refresh: DirectoryStage(conn, id), + Timeout: DirectoryCreatedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*directoryservice.DirectoryDescription); ok { + tfresource.SetLastError(err, errors.New(aws.StringValue(output.StageReason))) + + return output, err + } + + return nil, err +} + +func DirectoryDeleted(conn *directoryservice.DirectoryService, id string) (*directoryservice.DirectoryDescription, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{directoryservice.DirectoryStageActive, directoryservice.DirectoryStageDeleting}, + Target: []string{}, + Refresh: DirectoryStage(conn, id), + Timeout: DirectoryDeletedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*directoryservice.DirectoryDescription); ok { + tfresource.SetLastError(err, errors.New(aws.StringValue(output.StageReason))) + + return output, err + } + + return nil, err +} diff --git a/aws/resource_aws_directory_service_directory.go b/aws/resource_aws_directory_service_directory.go index ca74e62535e0..ba64d8030083 100644 --- a/aws/resource_aws_directory_service_directory.go +++ b/aws/resource_aws_directory_service_directory.go @@ -3,15 +3,16 @@ package aws import ( "fmt" "log" - "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/directoryservice" "github.com/hashicorp/aws-sdk-go-base/tfawserr" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "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/directoryservice/finder" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/directoryservice/waiter" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) func resourceAwsDirectoryServiceDirectory() *schema.Resource { @@ -387,35 +388,10 @@ func resourceAwsDirectoryServiceDirectoryCreate(d *schema.ResourceData, meta int d.SetId(directoryId) - // Wait for creation - log.Printf("[DEBUG] Waiting for DS (%q) to become available", d.Id()) - stateConf := &resource.StateChangeConf{ - Pending: []string{ - directoryservice.DirectoryStageRequested, - directoryservice.DirectoryStageCreating, - directoryservice.DirectoryStageCreated, - }, - Target: []string{directoryservice.DirectoryStageActive}, - Refresh: func() (interface{}, string, error) { - resp, err := dsconn.DescribeDirectories(&directoryservice.DescribeDirectoriesInput{ - DirectoryIds: []*string{aws.String(d.Id())}, - }) - if err != nil { - log.Printf("Error during creation of DS: %q", err.Error()) - return nil, "", err - } - - ds := resp.DirectoryDescriptions[0] - log.Printf("[DEBUG] Creation of DS %q is in following stage: %q.", - d.Id(), *ds.Stage) - return ds, *ds.Stage, nil - }, - Timeout: 60 * time.Minute, - } - if _, err := stateConf.WaitForState(); err != nil { - return fmt.Errorf( - "Error waiting for Directory Service (%s) to become available: %s", - d.Id(), err) + _, err = waiter.DirectoryCreated(dsconn, d.Id()) + + if err != nil { + return fmt.Errorf("error waiting for Directory Service Directory (%s) to create: %w", d.Id(), err) } if v, ok := d.GetOk("alias"); ok { @@ -468,22 +444,18 @@ func resourceAwsDirectoryServiceDirectoryRead(d *schema.ResourceData, meta inter defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig - input := directoryservice.DescribeDirectoriesInput{ - DirectoryIds: []*string{aws.String(d.Id())}, - } - out, err := dsconn.DescribeDirectories(&input) - if err != nil { - return err - - } + dir, err := finder.DirectoryByID(dsconn, d.Id()) - if len(out.DirectoryDescriptions) == 0 { - log.Printf("[WARN] Directory %s not found", d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Directory Service Directory (%s) not found, removing from state", d.Id()) d.SetId("") return nil } - dir := out.DirectoryDescriptions[0] + if err != nil { + return fmt.Errorf("error reading Directory Service Directory (%s): %w", d.Id(), err) + } + log.Printf("[DEBUG] Received DS directory: %s", dir) d.Set("access_url", dir.AccessUrl) @@ -554,44 +526,11 @@ func resourceAwsDirectoryServiceDirectoryDelete(d *schema.ResourceData, meta int return fmt.Errorf("error deleting Directory Service Directory (%s): %w", d.Id(), err) } - err = waitForDirectoryServiceDirectoryDeletion(conn, d.Id()) + _, err = waiter.DirectoryDeleted(conn, d.Id()) if err != nil { - return fmt.Errorf("error waiting for Directory Service (%s) to be deleted: %w", d.Id(), err) + return fmt.Errorf("error waiting for Directory Service Directory (%s) to delete: %w", d.Id(), err) } return nil } - -func waitForDirectoryServiceDirectoryDeletion(conn *directoryservice.DirectoryService, directoryID string) error { - stateConf := &resource.StateChangeConf{ - Pending: []string{ - directoryservice.DirectoryStageActive, - directoryservice.DirectoryStageDeleting, - }, - Target: []string{directoryservice.DirectoryStageDeleted}, - Refresh: func() (interface{}, string, error) { - resp, err := conn.DescribeDirectories(&directoryservice.DescribeDirectoriesInput{ - DirectoryIds: []*string{aws.String(directoryID)}, - }) - if err != nil { - if isAWSErr(err, directoryservice.ErrCodeEntityDoesNotExistException, "") { - return 42, directoryservice.DirectoryStageDeleted, nil - } - return nil, "error", err - } - - if len(resp.DirectoryDescriptions) == 0 || resp.DirectoryDescriptions[0] == nil { - return 42, directoryservice.DirectoryStageDeleted, nil - } - - ds := resp.DirectoryDescriptions[0] - log.Printf("[DEBUG] Deletion of Directory Service Directory %q is in following stage: %q.", directoryID, aws.StringValue(ds.Stage)) - return ds, aws.StringValue(ds.Stage), nil - }, - Timeout: 60 * time.Minute, - } - _, err := stateConf.WaitForState() - - return err -} diff --git a/aws/resource_aws_fsx_windows_file_system.go b/aws/resource_aws_fsx_windows_file_system.go index 1dbf1f7dae05..fb9df280df40 100644 --- a/aws/resource_aws_fsx_windows_file_system.go +++ b/aws/resource_aws_fsx_windows_file_system.go @@ -43,6 +43,18 @@ func resourceAwsFsxWindowsFileSystem() *schema.Resource { ForceNew: true, ConflictsWith: []string{"self_managed_active_directory"}, }, + "aliases": { + Type: schema.TypeSet, + Optional: true, + MaxItems: 50, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.All( + validation.StringLenBetween(4, 253), + // validation.StringMatch(regexp.MustCompile(`^[A-Za-z0-9]([.][A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])+$`), "must be in the fqdn format hostname.domain"), + ), + }, + }, "arn": { Type: schema.TypeString, Computed: true, @@ -265,6 +277,10 @@ func resourceAwsFsxWindowsFileSystemCreate(d *schema.ResourceData, meta interfac input.WindowsConfiguration.ActiveDirectoryId = aws.String(v.(string)) } + if v, ok := d.GetOk("aliases"); ok { + input.WindowsConfiguration.Aliases = expandStringSet(v.(*schema.Set)) + } + if v, ok := d.GetOk("deployment_type"); ok { input.WindowsConfiguration.DeploymentType = aws.String(v.(string)) } @@ -332,7 +348,15 @@ func resourceAwsFsxWindowsFileSystemUpdate(d *schema.ResourceData, meta interfac } } - if d.HasChangeExcept("tags_all") { + if d.HasChange("aliases") { + o, n := d.GetChange("aliases") + + if err := updateFsxAliases(conn, d.Id(), o.(*schema.Set), n.(*schema.Set), d.Timeout(schema.TimeoutUpdate)); err != nil { + return fmt.Errorf("error updating FSx Windows File System (%s) aliases: %w", d.Id(), err) + } + } + + if d.HasChangesExcept("tags_all", "aliases") { input := &fsx.UpdateFileSystemInput{ ClientRequestToken: aws.String(resource.UniqueId()), FileSystemId: aws.String(d.Id()), @@ -373,7 +397,7 @@ func resourceAwsFsxWindowsFileSystemUpdate(d *schema.ResourceData, meta interfac return fmt.Errorf("error updating FSx Windows File System (%s): %w", d.Id(), err) } - if err := waitForFsxFileSystemUpdateAdministrativeActionsStatusFileSystemUpdate(conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { + if err := waitForFsxFileSystemUpdateAdministrativeActionsStatusFileSystemUpdate(conn, d.Id(), fsx.AdministrativeActionTypeFileSystemUpdate, d.Timeout(schema.TimeoutUpdate)); err != nil { return fmt.Errorf("error waiting for FSx Windows File System (%s) update: %w", d.Id(), err) } } @@ -425,6 +449,10 @@ func resourceAwsFsxWindowsFileSystemRead(d *schema.ResourceData, meta interface{ d.Set("kms_key_id", filesystem.KmsKeyId) d.Set("storage_type", filesystem.StorageType) + if err := d.Set("aliases", aws.StringValueSlice(expandFsxAliasValues(filesystem.WindowsConfiguration.Aliases))); err != nil { + return fmt.Errorf("error setting aliases: %s", err) + } + if err := d.Set("network_interface_ids", aws.StringValueSlice(filesystem.NetworkInterfaceIds)); err != nil { return fmt.Errorf("error setting network_interface_ids: %w", err) } @@ -493,6 +521,60 @@ func resourceAwsFsxWindowsFileSystemDelete(d *schema.ResourceData, meta interfac return nil } +func expandFsxAliasValues(aliases []*fsx.Alias) []*string { + var alternateDNSNames []*string + + for _, alias := range aliases { + aName := alias.Name + alternateDNSNames = append(alternateDNSNames, aName) + } + + return alternateDNSNames +} + +func updateFsxAliases(conn *fsx.FSx, identifier string, oldSet *schema.Set, newSet *schema.Set, timeout time.Duration) error { + if newSet.Len() > 0 { + if newAliases := newSet.Difference(oldSet); newAliases.Len() > 0 { + + input := &fsx.AssociateFileSystemAliasesInput{ + FileSystemId: aws.String(identifier), + Aliases: expandStringSet(newAliases), + } + + _, err := conn.AssociateFileSystemAliases(input) + + if err != nil { + return fmt.Errorf("error associating aliases to FSx file system (%s): %w", identifier, err) + } + + if err := waitForFsxFileSystemUpdateAdministrativeActionsStatusFileSystemUpdate(conn, identifier, fsx.AdministrativeActionTypeFileSystemAliasAssociation, timeout); err != nil { + return fmt.Errorf("Error waiting for FSX Windows filesystem (%s) alias to be associated: %w", identifier, err) + } + } + } + + if oldSet.Len() > 0 { + if oldAliases := oldSet.Difference(newSet); oldAliases.Len() > 0 { + input := &fsx.DisassociateFileSystemAliasesInput{ + FileSystemId: aws.String(identifier), + Aliases: expandStringSet(oldAliases), + } + + _, err := conn.DisassociateFileSystemAliases(input) + + if err != nil { + return fmt.Errorf("error disassociating aliases from FSx file system (%s): %w", identifier, err) + } + + if err := waitForFsxFileSystemUpdateAdministrativeActionsStatusFileSystemUpdate(conn, identifier, fsx.AdministrativeActionTypeFileSystemAliasDisassociation, timeout); err != nil { + return fmt.Errorf("Error waiting for FSX Windows filesystem (%s) alias to disassociated: %w", identifier, err) + } + } + } + + return nil +} + func expandFsxSelfManagedActiveDirectoryConfigurationCreate(l []interface{}) *fsx.SelfManagedActiveDirectoryConfiguration { if len(l) == 0 || l[0] == nil { return nil diff --git a/aws/resource_aws_fsx_windows_file_system_test.go b/aws/resource_aws_fsx_windows_file_system_test.go index 20b4b679c8eb..f64f2852c64b 100644 --- a/aws/resource_aws_fsx_windows_file_system_test.go +++ b/aws/resource_aws_fsx_windows_file_system_test.go @@ -85,6 +85,7 @@ func TestAccAWSFsxWindowsFileSystem_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckFsxWindowsFileSystemExists(resourceName, &filesystem), testAccMatchResourceAttrRegionalARN(resourceName, "arn", "fsx", regexp.MustCompile(`file-system/fs-.+`)), + resource.TestCheckResourceAttr(resourceName, "aliases.#", "0"), resource.TestCheckResourceAttr(resourceName, "automatic_backup_retention_days", "7"), resource.TestCheckResourceAttr(resourceName, "copy_tags_to_backups", "false"), resource.TestMatchResourceAttr(resourceName, "daily_automatic_backup_start_time", regexp.MustCompile(`^\d\d:\d\d$`)), @@ -140,6 +141,7 @@ func TestAccAWSFsxWindowsFileSystem_singleAz2(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckFsxWindowsFileSystemExists(resourceName, &filesystem), testAccMatchResourceAttrRegionalARN(resourceName, "arn", "fsx", regexp.MustCompile(`file-system/fs-.+`)), + resource.TestCheckResourceAttr(resourceName, "aliases.#", "0"), resource.TestCheckResourceAttr(resourceName, "automatic_backup_retention_days", "7"), resource.TestCheckResourceAttr(resourceName, "copy_tags_to_backups", "false"), resource.TestMatchResourceAttr(resourceName, "daily_automatic_backup_start_time", regexp.MustCompile(`^\d\d:\d\d$`)), @@ -219,6 +221,7 @@ func TestAccAWSFsxWindowsFileSystem_multiAz(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckFsxWindowsFileSystemExists(resourceName, &filesystem), testAccMatchResourceAttrRegionalARN(resourceName, "arn", "fsx", regexp.MustCompile(`file-system/fs-.+`)), + resource.TestCheckResourceAttr(resourceName, "aliases.#", "0"), resource.TestCheckResourceAttr(resourceName, "automatic_backup_retention_days", "7"), resource.TestCheckResourceAttr(resourceName, "copy_tags_to_backups", "false"), resource.TestMatchResourceAttr(resourceName, "daily_automatic_backup_start_time", regexp.MustCompile(`^\d\d:\d\d$`)), @@ -273,6 +276,56 @@ func TestAccAWSFsxWindowsFileSystem_disappears(t *testing.T) { }) } +func TestAccAWSFsxWindowsFileSystem_aliases(t *testing.T) { + var filesystem1, filesystem2, filesystem3 fsx.FileSystem + resourceName := "aws_fsx_windows_file_system.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(fsx.EndpointsID, t) }, + ErrorCheck: testAccErrorCheck(t, fsx.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckFsxWindowsFileSystemDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsFsxWindowsFileSystemConfigAliases1("filesystem1.example.com"), + Check: resource.ComposeTestCheckFunc( + testAccCheckFsxWindowsFileSystemExists(resourceName, &filesystem1), + resource.TestCheckResourceAttr(resourceName, "aliases.#", "1"), + resource.TestCheckResourceAttr(resourceName, "aliases.0", "filesystem1.example.com"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "security_group_ids", + "skip_final_backup", + }, + }, + { + Config: testAccAwsFsxWindowsFileSystemConfigAliases2("filesystem2.example.com", "filesystem3.example.com"), + Check: resource.ComposeTestCheckFunc( + testAccCheckFsxWindowsFileSystemExists(resourceName, &filesystem2), + testAccCheckFsxWindowsFileSystemNotRecreated(&filesystem1, &filesystem2), + resource.TestCheckResourceAttr(resourceName, "aliases.#", "2"), + resource.TestCheckResourceAttr(resourceName, "aliases.0", "filesystem2.example.com"), + resource.TestCheckResourceAttr(resourceName, "aliases.1", "filesystem3.example.com"), + ), + }, + { + Config: testAccAwsFsxWindowsFileSystemConfigAliases1("filesystem3.example.com"), + Check: resource.ComposeTestCheckFunc( + testAccCheckFsxWindowsFileSystemExists(resourceName, &filesystem3), + testAccCheckFsxWindowsFileSystemNotRecreated(&filesystem2, &filesystem3), + resource.TestCheckResourceAttr(resourceName, "aliases.#", "1"), + resource.TestCheckResourceAttr(resourceName, "aliases.0", "filesystem3.example.com"), + ), + }, + }, + }) +} + func TestAccAWSFsxWindowsFileSystem_AutomaticBackupRetentionDays(t *testing.T) { var filesystem1, filesystem2, filesystem3 fsx.FileSystem resourceName := "aws_fsx_windows_file_system.test" @@ -861,6 +914,34 @@ resource "aws_directory_service_directory" "test" { ` } +func testAccAwsFsxWindowsFileSystemConfigAliases1(alias1 string) string { + return testAccAwsFsxWindowsFileSystemConfigBase() + fmt.Sprintf(` +resource "aws_fsx_windows_file_system" "test" { + active_directory_id = aws_directory_service_directory.test.id + skip_final_backup = true + storage_capacity = 32 + subnet_ids = [aws_subnet.test1.id] + throughput_capacity = 8 + + aliases = [%[1]q] +} +`, alias1) +} + +func testAccAwsFsxWindowsFileSystemConfigAliases2(alias1, alias2 string) string { + return testAccAwsFsxWindowsFileSystemConfigBase() + fmt.Sprintf(` +resource "aws_fsx_windows_file_system" "test" { + active_directory_id = aws_directory_service_directory.test.id + skip_final_backup = true + storage_capacity = 32 + subnet_ids = [aws_subnet.test1.id] + throughput_capacity = 8 + + aliases = [%[1]q, %[2]q] +} +`, alias1, alias2) +} + func testAccAwsFsxWindowsFileSystemConfigAutomaticBackupRetentionDays(automaticBackupRetentionDays int) string { return testAccAwsFsxWindowsFileSystemConfigBase() + fmt.Sprintf(` resource "aws_fsx_windows_file_system" "test" { diff --git a/website/docs/r/fsx_windows_file_system.html.markdown b/website/docs/r/fsx_windows_file_system.html.markdown index 4378b8970412..8498466b8742 100644 --- a/website/docs/r/fsx_windows_file_system.html.markdown +++ b/website/docs/r/fsx_windows_file_system.html.markdown @@ -56,6 +56,7 @@ The following arguments are supported: * `subnet_ids` - (Required) A list of IDs for the subnets that the file system will be accessible from. To specify more than a single subnet set `deployment_type` to `MULTI_AZ_1`. * `throughput_capacity` - (Required) Throughput (megabytes per second) of the file system in power of 2 increments. Minimum of `8` and maximum of `2048`. * `active_directory_id` - (Optional) The ID for an existing Microsoft Active Directory instance that the file system should join when it's created. Cannot be specified with `self_managed_active_directory`. +* `aliases` - (Optional) An array DNS alias names that you want to associate with the Amazon FSx file system. For more information, see [Working with DNS Aliases](https://docs.aws.amazon.com/fsx/latest/WindowsGuide/managing-dns-aliases.html) * `automatic_backup_retention_days` - (Optional) The number of days to retain automatic backups. Minimum of `0` and maximum of `90`. Defaults to `7`. Set to `0` to disable. * `copy_tags_to_backups` - (Optional) A boolean flag indicating whether tags on the file system should be copied to backups. Defaults to `false`. * `daily_automatic_backup_start_time` - (Optional) The preferred time (in `HH:MM` format) to take daily automatic backups, in the UTC time zone.