@@ -186,24 +186,49 @@ func resourceCluster() *schema.Resource {
186
186
ForceNew : true ,
187
187
ValidateFunc : verify .ValidARN ,
188
188
},
189
+ "manage_master_user_password" : {
190
+ Type : schema .TypeBool ,
191
+ Optional : true ,
192
+ ConflictsWith : []string {"master_password" , "master_password_wo" },
193
+ },
189
194
"master_password" : {
190
195
Type : schema .TypeString ,
191
196
Optional : true ,
192
197
Sensitive : true ,
193
- ConflictsWith : []string {"master_password_wo" },
198
+ ConflictsWith : []string {"manage_master_user_password" , " master_password_wo" },
194
199
},
195
200
"master_password_wo" : {
196
201
Type : schema .TypeString ,
197
202
Optional : true ,
198
203
WriteOnly : true ,
199
- ConflictsWith : []string {"master_password" },
204
+ ConflictsWith : []string {"manage_master_user_password" , " master_password" },
200
205
RequiredWith : []string {"master_password_wo_version" },
201
206
},
202
207
"master_password_wo_version" : {
203
208
Type : schema .TypeInt ,
204
209
Optional : true ,
205
210
RequiredWith : []string {"master_password_wo" },
206
211
},
212
+ "master_user_secret" : {
213
+ Type : schema .TypeList ,
214
+ Computed : true ,
215
+ Elem : & schema.Resource {
216
+ Schema : map [string ]* schema.Schema {
217
+ names .AttrKMSKeyID : {
218
+ Type : schema .TypeString ,
219
+ Computed : true ,
220
+ },
221
+ "secret_arn" : {
222
+ Type : schema .TypeString ,
223
+ Computed : true ,
224
+ },
225
+ "secret_status" : {
226
+ Type : schema .TypeString ,
227
+ Computed : true ,
228
+ },
229
+ },
230
+ },
231
+ },
207
232
"master_username" : {
208
233
Type : schema .TypeString ,
209
234
Optional : true ,
@@ -340,7 +365,7 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
340
365
// ModifyDBInstance afterwadocdb to prevent Terraform operators from API
341
366
// errors or needing to double apply.
342
367
var requiresModifyDbCluster bool
343
- inputM := & docdb.ModifyDBClusterInput {
368
+ inputMDBC := docdb.ModifyDBClusterInput {
344
369
ApplyImmediately : aws .Bool (true ),
345
370
}
346
371
@@ -352,7 +377,7 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
352
377
}
353
378
354
379
if _ , ok := d .GetOk ("snapshot_identifier" ); ok {
355
- input := & docdb.RestoreDBClusterFromSnapshotInput {
380
+ input := docdb.RestoreDBClusterFromSnapshotInput {
356
381
DBClusterIdentifier : aws .String (identifier ),
357
382
DeletionProtection : aws .Bool (d .Get (names .AttrDeletionProtection ).(bool )),
358
383
Engine : aws .String (d .Get (names .AttrEngine ).(string )),
@@ -365,12 +390,12 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
365
390
}
366
391
367
392
if v , ok := d .GetOk ("backup_retention_period" ); ok {
368
- inputM .BackupRetentionPeriod = aws .Int32 (int32 (v .(int )))
393
+ inputMDBC .BackupRetentionPeriod = aws .Int32 (int32 (v .(int )))
369
394
requiresModifyDbCluster = true
370
395
}
371
396
372
397
if v , ok := d .GetOk ("db_cluster_parameter_group_name" ); ok {
373
- inputM .DBClusterParameterGroupName = aws .String (v .(string ))
398
+ inputMDBC .DBClusterParameterGroupName = aws .String (v .(string ))
374
399
requiresModifyDbCluster = true
375
400
}
376
401
@@ -390,13 +415,18 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
390
415
input .KmsKeyId = aws .String (v .(string ))
391
416
}
392
417
418
+ if v , ok := d .GetOk ("manage_master_user_password" ); ok {
419
+ inputMDBC .ManageMasterUserPassword = aws .Bool (v .(bool ))
420
+ requiresModifyDbCluster = true
421
+ }
422
+
393
423
if v , ok := d .GetOk ("master_password" ); ok {
394
- inputM .MasterUserPassword = aws .String (v .(string ))
424
+ inputMDBC .MasterUserPassword = aws .String (v .(string ))
395
425
requiresModifyDbCluster = true
396
426
}
397
427
398
428
if masterPasswordWO != "" {
399
- inputM .MasterUserPassword = aws .String (masterPasswordWO )
429
+ inputMDBC .MasterUserPassword = aws .String (masterPasswordWO )
400
430
requiresModifyDbCluster = true
401
431
}
402
432
@@ -405,12 +435,12 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
405
435
}
406
436
407
437
if v , ok := d .GetOk ("preferred_backup_window" ); ok {
408
- inputM .PreferredBackupWindow = aws .String (v .(string ))
438
+ inputMDBC .PreferredBackupWindow = aws .String (v .(string ))
409
439
requiresModifyDbCluster = true
410
440
}
411
441
412
442
if v , ok := d .GetOk (names .AttrPreferredMaintenanceWindow ); ok {
413
- inputM .PreferredMaintenanceWindow = aws .String (v .(string ))
443
+ inputMDBC .PreferredMaintenanceWindow = aws .String (v .(string ))
414
444
requiresModifyDbCluster = true
415
445
}
416
446
@@ -423,15 +453,15 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
423
453
}
424
454
425
455
_ , err := tfresource .RetryWhenAWSErrMessageContains (ctx , propagationTimeout , func () (any , error ) {
426
- return conn .RestoreDBClusterFromSnapshot (ctx , input )
456
+ return conn .RestoreDBClusterFromSnapshot (ctx , & input )
427
457
}, errCodeInvalidParameterValue , "IAM role ARN value is invalid or does not include the required permissions" )
428
458
429
459
if err != nil {
430
460
return sdkdiag .AppendErrorf (diags , "creating DocumentDB Cluster (restore from snapshot) (%s): %s" , identifier , err )
431
461
}
432
462
} else if v , ok := d .GetOk ("restore_to_point_in_time" ); ok && len (v .([]any )) > 0 && v .([]any )[0 ] != nil {
433
463
tfMap := v .([]any )[0 ].(map [string ]any )
434
- input := & docdb.RestoreDBClusterToPointInTimeInput {
464
+ input := docdb.RestoreDBClusterToPointInTimeInput {
435
465
DBClusterIdentifier : aws .String (identifier ),
436
466
SourceDBClusterIdentifier : aws .String (tfMap ["source_cluster_identifier" ].(string )),
437
467
DeletionProtection : aws .Bool (d .Get (names .AttrDeletionProtection ).(bool )),
@@ -480,16 +510,19 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
480
510
}
481
511
482
512
_ , err := tfresource .RetryWhenAWSErrMessageContains (ctx , propagationTimeout , func () (any , error ) {
483
- return conn .RestoreDBClusterToPointInTime (ctx , input )
513
+ return conn .RestoreDBClusterToPointInTime (ctx , & input )
484
514
}, errCodeInvalidParameterValue , "IAM role ARN value is invalid or does not include the required permissions" )
485
515
if err != nil {
486
516
return sdkdiag .AppendErrorf (diags , "creating DocumentDB Cluster (restore to point-in-time) (%s): %s" , identifier , err )
487
517
}
488
518
} else {
489
519
// Secondary DocDB clusters part of a global cluster will not supply the master_password
490
520
if _ , ok := d .GetOk ("global_cluster_identifier" ); ! ok {
491
- if _ , ok := d .GetOk ("master_password" ); ! ok && masterPasswordWO == "" {
492
- return sdkdiag .AppendErrorf (diags , `provider.aws: aws_docdb_cluster: %s: "master_password", "master_password_wo": required field is not set` , identifier )
521
+ // If manage_master_user_password is true, we don't need master_password
522
+ if v , ok := d .GetOk ("manage_master_user_password" ); ! ok || ! v .(bool ) {
523
+ if _ , ok := d .GetOk ("master_password" ); ! ok && masterPasswordWO == "" {
524
+ return sdkdiag .AppendErrorf (diags , `provider.aws: aws_docdb_cluster: %s: "master_password", "master_password_wo": required field is not set` , identifier )
525
+ }
493
526
}
494
527
}
495
528
@@ -500,7 +533,7 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
500
533
}
501
534
}
502
535
503
- input := & docdb.CreateDBClusterInput {
536
+ input := docdb.CreateDBClusterInput {
504
537
DBClusterIdentifier : aws .String (identifier ),
505
538
DeletionProtection : aws .Bool (d .Get (names .AttrDeletionProtection ).(bool )),
506
539
Engine : aws .String (d .Get (names .AttrEngine ).(string )),
@@ -540,12 +573,16 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
540
573
input .KmsKeyId = aws .String (v .(string ))
541
574
}
542
575
543
- if v , ok := d .GetOk ("master_password" ); ok {
544
- input .MasterUserPassword = aws .String (v .(string ))
545
- }
576
+ if v , ok := d .GetOk ("manage_master_user_password" ); ok {
577
+ input .ManageMasterUserPassword = aws .Bool (v .(bool ))
578
+ } else {
579
+ if v , ok := d .GetOk ("master_password" ); ok {
580
+ input .MasterUserPassword = aws .String (v .(string ))
581
+ }
546
582
547
- if masterPasswordWO != "" {
548
- input .MasterUserPassword = aws .String (masterPasswordWO )
583
+ if masterPasswordWO != "" {
584
+ input .MasterUserPassword = aws .String (masterPasswordWO )
585
+ }
549
586
}
550
587
551
588
if v , ok := d .GetOk (names .AttrPort ); ok {
@@ -573,7 +610,7 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
573
610
}
574
611
575
612
_ , err := tfresource .RetryWhenAWSErrMessageContains (ctx , propagationTimeout , func () (any , error ) {
576
- return conn .CreateDBCluster (ctx , input )
613
+ return conn .CreateDBCluster (ctx , & input )
577
614
}, errCodeInvalidParameterValue , "IAM role ARN value is invalid or does not include the required permissions" )
578
615
579
616
if err != nil {
@@ -588,9 +625,9 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
588
625
}
589
626
590
627
if requiresModifyDbCluster {
591
- inputM .DBClusterIdentifier = aws .String (d .Id ())
628
+ inputMDBC .DBClusterIdentifier = aws .String (d .Id ())
592
629
593
- _ , err := conn .ModifyDBCluster (ctx , inputM )
630
+ _ , err := conn .ModifyDBCluster (ctx , & inputMDBC )
594
631
595
632
if err != nil {
596
633
return sdkdiag .AppendErrorf (diags , "modifying DocumentDB Cluster (%s): %s" , d .Id (), err )
@@ -650,18 +687,28 @@ func resourceClusterRead(ctx context.Context, d *schema.ResourceData, meta any)
650
687
d .Set (names .AttrEngine , dbc .Engine )
651
688
d .Set (names .AttrHostedZoneID , dbc .HostedZoneId )
652
689
d .Set (names .AttrKMSKeyID , dbc .KmsKeyId )
690
+ if v := dbc .MasterUserSecret ; v != nil {
691
+ tfList := []any {map [string ]any {
692
+ names .AttrKMSKeyID : aws .ToString (v .KmsKeyId ),
693
+ "secret_arn" : aws .ToString (v .SecretArn ),
694
+ "secret_status" : aws .ToString (v .SecretStatus ),
695
+ }}
696
+ if err := d .Set ("master_user_secret" , tfList ); err != nil {
697
+ return sdkdiag .AppendErrorf (diags , "setting master_user_secret: %s" , err )
698
+ }
699
+ } else {
700
+ d .Set ("master_user_secret" , nil )
701
+ }
653
702
d .Set ("master_username" , dbc .MasterUsername )
654
703
d .Set (names .AttrPort , dbc .Port )
655
704
d .Set ("preferred_backup_window" , dbc .PreferredBackupWindow )
656
705
d .Set (names .AttrPreferredMaintenanceWindow , dbc .PreferredMaintenanceWindow )
657
706
d .Set ("reader_endpoint" , dbc .ReaderEndpoint )
658
707
d .Set (names .AttrStorageEncrypted , dbc .StorageEncrypted )
659
708
d .Set (names .AttrStorageType , dbc .StorageType )
660
- var securityGroupIDs []string
661
- for _ , v := range dbc .VpcSecurityGroups {
662
- securityGroupIDs = append (securityGroupIDs , aws .ToString (v .VpcSecurityGroupId ))
663
- }
664
- d .Set (names .AttrVPCSecurityGroupIDs , securityGroupIDs )
709
+ d .Set (names .AttrVPCSecurityGroupIDs , tfslices .ApplyToAll (dbc .VpcSecurityGroups , func (v awstypes.VpcSecurityGroupMembership ) string {
710
+ return aws .ToString (v .VpcSecurityGroupId )
711
+ }))
665
712
666
713
return diags
667
714
}
@@ -671,7 +718,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any
671
718
conn := meta .(* conns.AWSClient ).DocDBClient (ctx )
672
719
673
720
if d .HasChangesExcept (names .AttrTags , names .AttrTagsAll , "global_cluster_identifier" , "skip_final_snapshot" ) {
674
- input := & docdb.ModifyDBClusterInput {
721
+ input := docdb.ModifyDBClusterInput {
675
722
ApplyImmediately : aws .Bool (d .Get (names .AttrApplyImmediately ).(bool )),
676
723
DBClusterIdentifier : aws .String (d .Id ()),
677
724
}
@@ -700,6 +747,10 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any
700
747
input .EngineVersion = aws .String (d .Get (names .AttrEngineVersion ).(string ))
701
748
}
702
749
750
+ if d .HasChange ("manage_master_user_password" ) {
751
+ input .ManageMasterUserPassword = aws .Bool (d .Get ("manage_master_user_password" ).(bool ))
752
+ }
753
+
703
754
if d .HasChange ("master_password" ) {
704
755
input .MasterUserPassword = aws .String (d .Get ("master_password" ).(string ))
705
756
}
@@ -736,9 +787,12 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any
736
787
}
737
788
}
738
789
739
- _ , err := tfresource .RetryWhen (ctx , 5 * time .Minute ,
790
+ const (
791
+ timeout = 5 * time .Minute
792
+ )
793
+ _ , err := tfresource .RetryWhen (ctx , timeout ,
740
794
func () (any , error ) {
741
- return conn .ModifyDBCluster (ctx , input )
795
+ return conn .ModifyDBCluster (ctx , & input )
742
796
},
743
797
func (err error ) (bool , error ) {
744
798
if tfawserr .ErrMessageContains (err , errCodeInvalidParameterValue , "IAM role ARN value is invalid or does not include the required permissions" ) {
@@ -791,7 +845,7 @@ func resourceClusterDelete(ctx context.Context, d *schema.ResourceData, meta any
791
845
conn := meta .(* conns.AWSClient ).DocDBClient (ctx )
792
846
793
847
skipFinalSnapshot := d .Get ("skip_final_snapshot" ).(bool )
794
- input := & docdb.DeleteDBClusterInput {
848
+ input := docdb.DeleteDBClusterInput {
795
849
DBClusterIdentifier : aws .String (d .Id ()),
796
850
SkipFinalSnapshot : aws .Bool (skipFinalSnapshot ),
797
851
}
@@ -813,7 +867,7 @@ func resourceClusterDelete(ctx context.Context, d *schema.ResourceData, meta any
813
867
log .Printf ("[DEBUG] Deleting DocumentDB Cluster: %s" , d .Id ())
814
868
_ , err := tfresource .RetryWhen (ctx , d .Timeout (schema .TimeoutDelete ),
815
869
func () (any , error ) {
816
- return conn .DeleteDBCluster (ctx , input )
870
+ return conn .DeleteDBCluster (ctx , & input )
817
871
},
818
872
func (err error ) (bool , error ) {
819
873
if errs .IsAErrorMessageContains [* awstypes.InvalidDBClusterStateFault ](err , "is not currently in the available state" ) {
@@ -876,12 +930,12 @@ func diffCloudWatchLogsExportConfiguration(old, new []any) ([]any, []any) {
876
930
}
877
931
878
932
func removeClusterFromGlobalCluster (ctx context.Context , conn * docdb.Client , clusterARN , globalClusterID string , timeout time.Duration ) error {
879
- input := & docdb.RemoveFromGlobalClusterInput {
933
+ input := docdb.RemoveFromGlobalClusterInput {
880
934
DbClusterIdentifier : aws .String (clusterARN ),
881
935
GlobalClusterIdentifier : aws .String (globalClusterID ),
882
936
}
883
937
884
- _ , err := conn .RemoveFromGlobalCluster (ctx , input )
938
+ _ , err := conn .RemoveFromGlobalCluster (ctx , & input )
885
939
886
940
if errs.IsA [* awstypes.DBClusterNotFoundFault ](err ) || errs.IsA [* awstypes.GlobalClusterNotFoundFault ](err ) ||
887
941
tfawserr .ErrMessageContains (err , errCodeInvalidParameterValue , "is not found in global cluster" ) {
@@ -904,10 +958,10 @@ func removeClusterFromGlobalCluster(ctx context.Context, conn *docdb.Client, clu
904
958
}
905
959
906
960
func findDBClusterByID (ctx context.Context , conn * docdb.Client , id string ) (* awstypes.DBCluster , error ) {
907
- input := & docdb.DescribeDBClustersInput {
961
+ input := docdb.DescribeDBClustersInput {
908
962
DBClusterIdentifier : aws .String (id ),
909
963
}
910
- output , err := findDBCluster (ctx , conn , input , tfslices .PredicateTrue [* awstypes.DBCluster ]())
964
+ output , err := findDBCluster (ctx , conn , & input , tfslices .PredicateTrue [* awstypes.DBCluster ]())
911
965
912
966
if err != nil {
913
967
return nil , err
@@ -924,9 +978,9 @@ func findDBClusterByID(ctx context.Context, conn *docdb.Client, id string) (*aws
924
978
}
925
979
926
980
func findClusterByARN (ctx context.Context , conn * docdb.Client , arn string ) (* awstypes.DBCluster , error ) {
927
- input := & docdb.DescribeDBClustersInput {}
981
+ input := docdb.DescribeDBClustersInput {}
928
982
929
- return findDBCluster (ctx , conn , input , func (v * awstypes.DBCluster ) bool {
983
+ return findDBCluster (ctx , conn , & input , func (v * awstypes.DBCluster ) bool {
930
984
return aws .ToString (v .DBClusterArn ) == arn
931
985
})
932
986
}
0 commit comments