Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/44636.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_directory_service_directory: add `enable_directory_data_access` argument
```
167 changes: 153 additions & 14 deletions internal/service/ds/directory.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ func resourceDirectory() *schema.Resource {
},
},
},
"enable_directory_data_access": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
}
}
Expand Down Expand Up @@ -257,7 +262,6 @@ func resourceDirectoryCreate(ctx context.Context, d *schema.ResourceData, meta a

return nil
}, tfresource.WithPollInterval(1*time.Minute))

if err != nil {
return sdkdiag.AppendFromErr(diags, fmt.Errorf("creating Directory Service %s Directory (%s): %w", creator.TypeName(), name, err))
}
Expand All @@ -280,6 +284,30 @@ func resourceDirectoryCreate(ctx context.Context, d *schema.ResourceData, meta a
}
}

if v, ok := d.GetOk("enable_directory_data_access"); ok && v.(bool) {
if err := enableDirectoryDataAccess(ctx, conn, d.Id()); err != nil {
sdkdiag.AppendFromErr(diags, err)
}
err := tfresource.Retry(ctx, d.Timeout(schema.TimeoutCreate), func(ctx context.Context) *tfresource.RetryError {
if err := waitDirectoryDataAccess(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil {
if use, ok := errs.As[*retry.UnexpectedStateError](err); ok {
if use.State == string(awstypes.DataAccessStatusFailed) {
tflog.Info(ctx, "retrying failed Directory Data Access enablement", map[string]any{
"directory_id": d.Id(),
})
return tfresource.RetryableError(err)
}
}
return tfresource.NonRetryableError(err)
}

return nil
}, tfresource.WithPollInterval(1*time.Minute))
if err != nil {
return sdkdiag.AppendFromErr(diags, fmt.Errorf("enabling directory service data access: %w", err))
}
}

return append(diags, resourceDirectoryRead(ctx, d, meta)...)
}

Expand Down Expand Up @@ -334,6 +362,16 @@ func resourceDirectoryRead(ctx context.Context, d *schema.ResourceData, meta any
d.Set("vpc_settings", nil)
}

dda, err := getDirectoryDataAccess(ctx, conn, d.Id())
if err != nil {
return sdkdiag.AppendErrorf(diags, "reading directory data access: %s", err)
}
if dda.DataAccessStatus == awstypes.DataAccessStatusEnabled {
d.Set("enable_directory_data_access", true)
} else {
d.Set("enable_directory_data_access", false)
}

return diags
}

Expand All @@ -359,6 +397,37 @@ func resourceDirectoryUpdate(ctx context.Context, d *schema.ResourceData, meta a
}
}

if d.HasChange("enable_directory_data_access") {
if _, ok := d.GetOk("enable_directory_data_access"); ok {
if err := enableDirectoryDataAccess(ctx, conn, d.Id()); err != nil {
return sdkdiag.AppendFromErr(diags, err)
}
} else {
if err := disableDirectoryDataAccess(ctx, conn, d.Id()); err != nil {
return sdkdiag.AppendFromErr(diags, err)
}
}

err := tfresource.Retry(ctx, d.Timeout(schema.TimeoutCreate), func(ctx context.Context) *tfresource.RetryError {
if err := waitDirectoryDataAccess(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil {
if use, ok := errs.As[*retry.UnexpectedStateError](err); ok {
if use.State == string(awstypes.DataAccessStatusFailed) {
tflog.Info(ctx, "retrying failed Directory Data Access enablement", map[string]any{
"directory_id": d.Id(),
})
return tfresource.RetryableError(err)
}
}
return tfresource.NonRetryableError(err)
}

return nil
}, tfresource.WithPollInterval(1*time.Minute))
if err != nil {
return sdkdiag.AppendFromErr(diags, fmt.Errorf("enabling directory service data access: %w", err))
}
}

return append(diags, resourceDirectoryRead(ctx, d, meta)...)
}

Expand Down Expand Up @@ -426,7 +495,6 @@ func (c adConnectorCreator) Create(ctx context.Context, conn *directoryservice.C
}

output, err := conn.ConnectDirectory(ctx, input)

if err != nil {
return err
}
Expand Down Expand Up @@ -466,7 +534,6 @@ func (c microsoftADCreator) Create(ctx context.Context, conn *directoryservice.C
}

output, err := conn.CreateMicrosoftAD(ctx, input)

if err != nil {
return err
}
Expand Down Expand Up @@ -509,7 +576,6 @@ func (c simpleADCreator) Create(ctx context.Context, conn *directoryservice.Clie
}

output, err := conn.CreateDirectory(ctx, input)

if err != nil {
return err
}
Expand All @@ -526,7 +592,6 @@ func createAlias(ctx context.Context, conn *directoryservice.Client, directoryID
}

_, err := conn.CreateAlias(ctx, input)

if err != nil {
return fmt.Errorf("creating Directory Service Directory (%s) alias (%s): %w", directoryID, alias, err)
}
Expand All @@ -540,7 +605,6 @@ func disableSSO(ctx context.Context, conn *directoryservice.Client, directoryID
}

_, err := conn.DisableSso(ctx, input)

if err != nil {
return fmt.Errorf("disabling Directory Service Directory (%s) SSO: %w", directoryID, err)
}
Expand All @@ -554,19 +618,100 @@ func enableSSO(ctx context.Context, conn *directoryservice.Client, directoryID s
}

_, err := conn.EnableSso(ctx, input)

if err != nil {
return fmt.Errorf("enabling Directory Service Directory (%s) SSO: %w", directoryID, err)
}

return nil
}

func enableDirectoryDataAccess(ctx context.Context, conn *directoryservice.Client, directoryID string) error {
input := &directoryservice.EnableDirectoryDataAccessInput{
DirectoryId: aws.String(directoryID),
}

_, err := conn.EnableDirectoryDataAccess(ctx, input)
if err != nil {
return fmt.Errorf("enabling Directory Data Access for Directory Service Directory (%s): %w", directoryID, err)
}

return nil
}

func disableDirectoryDataAccess(ctx context.Context, conn *directoryservice.Client, directoryID string) error {
input := &directoryservice.DisableDirectoryDataAccessInput{
DirectoryId: aws.String(directoryID),
}

_, err := conn.DisableDirectoryDataAccess(ctx, input)
if err != nil {
return fmt.Errorf("disabling Directory Data Access for Directory Service Directory (%s): %w", directoryID, err)
}

return nil
}

func getDirectoryDataAccess(ctx context.Context, conn *directoryservice.Client, directoryID string) (*directoryservice.DescribeDirectoryDataAccessOutput, error) {
input := directoryservice.DescribeDirectoryDataAccessInput{
DirectoryId: aws.String(directoryID),
}

dda, err := conn.DescribeDirectoryDataAccess(ctx, &input)
if err != nil {
return nil, fmt.Errorf("describing Directory Data Access for Directory Service Directory (%s): %w", directoryID, err)
}

return dda, nil
}

func statusDirectoryDataAccess(ctx context.Context, conn *directoryservice.Client, directoryID string) retry.StateRefreshFunc {
return func() (any, string, error) {
output, err := getDirectoryDataAccess(ctx, conn, directoryID)

if tfresource.NotFound(err) {
return nil, "", nil
}

if err != nil {
return nil, "", err
}

return output, string(output.DataAccessStatus), nil
}
}

func waitDirectoryDataAccess(ctx context.Context, conn *directoryservice.Client, directoryID string, timeout time.Duration) error {
stateConf := &retry.StateChangeConf{
Pending: enum.Slice(string(awstypes.DataAccessStatusEnabling), string(awstypes.DataAccessStatusDisabling)),
Target: enum.Slice(string(awstypes.DataAccessStatusEnabled), string(awstypes.DataAccessStatusDisabled)),
Refresh: statusDirectoryDataAccess(ctx, conn, directoryID),
Timeout: timeout,
Delay: 1 * time.Minute,
MinTimeout: 10 * time.Second,
}

outputRaw, err := stateConf.WaitForStateContext(ctx)

// Wrap any error returned with waiting message
defer func() {
if err != nil {
err = fmt.Errorf("waiting for completion: %w", err)
}
}()

if output, ok := outputRaw.(*directoryservice.DescribeDirectoryDataAccessOutput); ok {
tfresource.SetLastError(err, errors.New(aws.ToString((*string)(&output.DataAccessStatus))))

return err
}

return err
}

func updateNumberOfDomainControllers(ctx context.Context, conn *directoryservice.Client, directoryID string, desiredNumber int, timeout time.Duration, optFns ...func(*directoryservice.Options)) error {
oldDomainControllers, err := findDomainControllers(ctx, conn, &directoryservice.DescribeDomainControllersInput{
DirectoryId: aws.String(directoryID),
}, optFns...)

if err != nil {
return fmt.Errorf("reading Directory Service Directory (%s) domain controllers: %w", directoryID, err)
}
Expand All @@ -577,15 +722,13 @@ func updateNumberOfDomainControllers(ctx context.Context, conn *directoryservice
}

_, err = conn.UpdateNumberOfDomainControllers(ctx, input, optFns...)

if err != nil {
return fmt.Errorf("updating Directory Service Directory (%s) number of domain controllers (%d): %w", directoryID, desiredNumber, err)
}

newDomainControllers, err := findDomainControllers(ctx, conn, &directoryservice.DescribeDomainControllersInput{
DirectoryId: aws.String(directoryID),
}, optFns...)

if err != nil {
return fmt.Errorf("reading Directory Service Directory (%s) domain controllers: %w", directoryID, err)
}
Expand Down Expand Up @@ -628,7 +771,6 @@ func updateNumberOfDomainControllers(ctx context.Context, conn *directoryservice

func findDirectory(ctx context.Context, conn *directoryservice.Client, input *directoryservice.DescribeDirectoriesInput) (*awstypes.DirectoryDescription, error) {
output, err := findDirectories(ctx, conn, input)

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -666,7 +808,6 @@ func findDirectoryByID(ctx context.Context, conn *directoryservice.Client, id st
}

output, err := findDirectory(ctx, conn, input)

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -753,7 +894,6 @@ func waitDirectoryDeleted(ctx context.Context, conn *directoryservice.Client, id

func findDomainController(ctx context.Context, conn *directoryservice.Client, input *directoryservice.DescribeDomainControllersInput, optFns ...func(*directoryservice.Options)) (*awstypes.DomainController, error) {
output, err := findDomainControllers(ctx, conn, input, optFns...)

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -792,7 +932,6 @@ func findDomainControllerByTwoPartKey(ctx context.Context, conn *directoryservic
}

output, err := findDomainController(ctx, conn, input, optFns...)

if err != nil {
return nil, err
}
Expand Down
Loading
Loading