diff --git a/.changelog/45140.txt b/.changelog/45140.txt new file mode 100644 index 000000000000..d0986bcc79e3 --- /dev/null +++ b/.changelog/45140.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/aws_docdb_cluster: Add `network_type` argument +``` + +```release-note:enhancement +resource/aws_docdb_subnet_group: Add `supported_network_types` attribute +``` diff --git a/internal/service/docdb/cluster.go b/internal/service/docdb/cluster.go index b672d280ece3..ff34508d28b0 100644 --- a/internal/service/docdb/cluster.go +++ b/internal/service/docdb/cluster.go @@ -236,6 +236,12 @@ func resourceCluster() *schema.Resource { Computed: true, ForceNew: true, }, + "network_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(networkType_Values(), false), + }, names.AttrPort: { Type: schema.TypeInt, Optional: true, @@ -486,6 +492,10 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any requiresModifyDbCluster = true } + if v, ok := d.GetOk("network_type"); ok { + input.NetworkType = aws.String(v.(string)) + } + if v, ok := d.GetOk(names.AttrPort); ok { input.Port = aws.Int32(int32(v.(int))) } @@ -557,6 +567,10 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any input.KmsKeyId = aws.String(v.(string)) } + if v, ok := d.GetOk("network_type"); ok { + input.NetworkType = aws.String(v.(string)) + } + if v, ok := d.GetOk(names.AttrPort); ok { input.Port = aws.Int32(int32(v.(int))) } @@ -649,6 +663,10 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any } } + if v, ok := d.GetOk("network_type"); ok { + input.NetworkType = aws.String(v.(string)) + } + if v, ok := d.GetOk(names.AttrPort); ok { input.Port = aws.Int32(int32(v.(int))) } @@ -768,6 +786,7 @@ func resourceClusterRead(ctx context.Context, d *schema.ResourceData, meta any) d.Set("master_user_secret", nil) } d.Set("master_username", dbc.MasterUsername) + d.Set("network_type", dbc.NetworkType) d.Set(names.AttrPort, dbc.Port) d.Set("preferred_backup_window", dbc.PreferredBackupWindow) d.Set(names.AttrPreferredMaintenanceWindow, dbc.PreferredMaintenanceWindow) diff --git a/internal/service/docdb/cluster_test.go b/internal/service/docdb/cluster_test.go index 8656f91de0c3..cb3a8fe37dcb 100644 --- a/internal/service/docdb/cluster_test.go +++ b/internal/service/docdb/cluster_test.go @@ -106,6 +106,36 @@ func TestAccDocDBCluster_basic(t *testing.T) { }) } +func TestAccDocDBCluster_networkType(t *testing.T) { + ctx := acctest.Context(t) + var dbCluster awstypes.DBCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_docdb_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.DocDBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckClusterDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccClusterConfig_networkType(rName, "IPV4"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckClusterExists(ctx, resourceName, &dbCluster), + resource.TestCheckResourceAttr(resourceName, "network_type", "IPV4"), + ), + }, + { + Config: testAccClusterConfig_networkType(rName, "DUAL"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckClusterExists(ctx, resourceName, &dbCluster), + resource.TestCheckResourceAttr(resourceName, "network_type", "DUAL"), + ), + }, + }, + }) +} + func TestAccDocDBCluster_disappears(t *testing.T) { ctx := acctest.Context(t) var v awstypes.DBCluster @@ -1733,6 +1763,27 @@ resource "aws_docdb_cluster" "test" { `, rName, passwordConfig)) } +func testAccClusterConfig_networkType(rName string, networkType string) string { + return acctest.ConfigCompose( + acctest.ConfigVPCWithSubnetsIPv6(rName, 2), + fmt.Sprintf(` +resource "aws_docdb_subnet_group" "test" { + name = %[1]q + subnet_ids = aws_subnet.test[*].id +} + +resource "aws_docdb_cluster" "test" { + cluster_identifier = %[1]q + db_subnet_group_name = aws_docdb_subnet_group.test.name + master_password = "avoid-plaintext-passwords" + master_username = "tfacctest" + skip_final_snapshot = true + network_type = %[2]q + apply_immediately = true +} +`, rName, networkType)) +} + func testAccClusterConfig_serverless(rName string, minCapacity, maxCapacity float64) string { return acctest.ConfigCompose(fmt.Sprintf(` resource "aws_docdb_cluster" "test" { diff --git a/internal/service/docdb/consts.go b/internal/service/docdb/consts.go index 10cf336db7f5..7c5aa8de6877 100644 --- a/internal/service/docdb/consts.go +++ b/internal/service/docdb/consts.go @@ -58,6 +58,18 @@ const ( globalClusterStatusUpgrading = "upgrading" ) +const ( + networkTypeDual = "DUAL" + networkTypeIPv4 = "IPV4" +) + +func networkType_Values() []string { + return []string{ + networkTypeDual, + networkTypeIPv4, + } +} + const ( storageTypeIOpt1 = "iopt1" storageTypeStandard = "standard" diff --git a/internal/service/docdb/subnet_group.go b/internal/service/docdb/subnet_group.go index 96abcbecf98a..9b4fafdaaf02 100644 --- a/internal/service/docdb/subnet_group.go +++ b/internal/service/docdb/subnet_group.go @@ -69,6 +69,11 @@ func resourceSubnetGroup() *schema.Resource { MinItems: 1, Elem: &schema.Schema{Type: schema.TypeString}, }, + "supported_network_types": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, names.AttrTags: tftags.TagsSchema(), names.AttrTagsAll: tftags.TagsSchemaComputed(), }, @@ -123,6 +128,7 @@ func resourceSubnetGroupRead(ctx context.Context, d *schema.ResourceData, meta a subnetIDs = append(subnetIDs, aws.ToString(v.SubnetIdentifier)) } d.Set(names.AttrSubnetIDs, subnetIDs) + d.Set("supported_network_types", subnetGroup.SupportedNetworkTypes) return diags } diff --git a/internal/service/docdb/subnet_group_test.go b/internal/service/docdb/subnet_group_test.go index f23880bc586e..9680266528b8 100644 --- a/internal/service/docdb/subnet_group_test.go +++ b/internal/service/docdb/subnet_group_test.go @@ -41,6 +41,8 @@ func TestAccDocDBSubnetGroup_basic(t *testing.T) { resource.TestCheckResourceAttrPair(resourceName, names.AttrID, resourceName, names.AttrName), resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "2"), + resource.TestCheckResourceAttr(resourceName, "supported_network_types.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "supported_network_types.*", "IPV4"), resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "0"), ), }, @@ -251,6 +253,32 @@ func TestAccDocDBSubnetGroup_tags(t *testing.T) { }) } +func TestAccDocDBSubnetGroup_dualStack(t *testing.T) { + ctx := acctest.Context(t) + var v awstypes.DBSubnetGroup + + resourceName := "aws_docdb_subnet_group.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.DocDBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckSubnetGroupDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccSubnetGroupConfig_dualStack(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckSubnetGroupExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "supported_network_types.#", "2"), + resource.TestCheckTypeSetElemAttr(resourceName, "supported_network_types.*", "IPV4"), + resource.TestCheckTypeSetElemAttr(resourceName, "supported_network_types.*", "DUAL"), + ), + }, + }, + }) +} + func testAccCheckSubnetGroupDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).DocDBClient(ctx) @@ -369,3 +397,12 @@ resource "aws_docdb_subnet_group" "test" { } `, rName, tagKey1, tagValue1, tagKey2, tagValue2)) } + +func testAccSubnetGroupConfig_dualStack(rName string) string { + return acctest.ConfigCompose(acctest.ConfigVPCWithSubnetsIPv6(rName, 2), fmt.Sprintf(` +resource "aws_docdb_subnet_group" "test" { + name = %[1]q + subnet_ids = aws_subnet.test[*].id +} +`, rName)) +} diff --git a/website/docs/r/docdb_cluster.html.markdown b/website/docs/r/docdb_cluster.html.markdown index 6661eb06a7a1..1782e8ff02e1 100644 --- a/website/docs/r/docdb_cluster.html.markdown +++ b/website/docs/r/docdb_cluster.html.markdown @@ -71,6 +71,7 @@ This resource supports the following arguments: show up in logs. Please refer to the DocumentDB Naming Constraints. Conflicts with `master_password` and `manage_master_user_password`. * `master_password_wo_version` - (Optional) Used together with `master_password_wo` to trigger an update. Increment this value when an update to the `master_password_wo` is required. * `master_username` - (Required unless a `snapshot_identifier` or unless a `global_cluster_identifier` is provided when the cluster is the "secondary" cluster of a global database) Username for the master DB user. +* `network_type` - The network type of the DB cluster (`IPV4` or `DUAL`). * `port` - (Optional) The port on which the DB accepts connections * `preferred_backup_window` - (Optional) The daily time range during which automated backups are created if automated backups are enabled using the BackupRetentionPeriod parameter.Time in UTC Default: A 30-minute window selected at random from an 8-hour block of time per regionE.g., 04:00-09:00 diff --git a/website/docs/r/docdb_subnet_group.html.markdown b/website/docs/r/docdb_subnet_group.html.markdown index f505c72ac7c8..5eb1a304e095 100644 --- a/website/docs/r/docdb_subnet_group.html.markdown +++ b/website/docs/r/docdb_subnet_group.html.markdown @@ -40,6 +40,7 @@ This resource exports the following attributes in addition to the arguments abov * `id` - The docDB subnet group name. * `arn` - The ARN of the docDB subnet group. +* `supported_network_types` - The network type of the docDB subnet group (`IPV4` or `DUAL`). * `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block). ## Import