diff --git a/.changelog/28434.txt b/.changelog/28434.txt new file mode 100644 index 00000000000..7c9c4a3ad92 --- /dev/null +++ b/.changelog/28434.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/aws_db_instance: Add `listener_endpoint` attribute +``` + +```release-note:enhancement +resource/aws_db_instance: Add plan time validations for `backup_retention_period`, `monitoring_interval`, and `monitoring_role_arn` +``` \ No newline at end of file diff --git a/internal/service/rds/instance.go b/internal/service/rds/instance.go index dff77c99a67..c62ece13b48 100644 --- a/internal/service/rds/instance.go +++ b/internal/service/rds/instance.go @@ -121,9 +121,10 @@ func ResourceInstance() *schema.Resource { ForceNew: true, }, "backup_retention_period": { - Type: schema.TypeInt, - Optional: true, - Computed: true, + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.IntBetween(0, 35), }, "backup_window": { Type: schema.TypeString, @@ -294,6 +295,26 @@ func ResourceInstance() *schema.Resource { Optional: true, Computed: true, }, + "listener_endpoint": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Computed: true, + }, + "hosted_zone_id": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, "maintenance_window": { Type: schema.TypeString, Optional: true, @@ -318,14 +339,16 @@ func ResourceInstance() *schema.Resource { }, }, "monitoring_interval": { - Type: schema.TypeInt, - Optional: true, - Default: 0, + Type: schema.TypeInt, + Optional: true, + Default: 0, + ValidateFunc: validation.IntInSlice([]int{0, 1, 5, 10, 15, 30, 60}), }, "monitoring_role_arn": { - Type: schema.TypeString, - Optional: true, - Computed: true, + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: verify.ValidARN, }, "multi_az": { Type: schema.TypeBool, @@ -1644,6 +1667,14 @@ func resourceInstanceRead(ctx context.Context, d *schema.ResourceData, meta inte d.Set("port", v.Endpoint.Port) } + if v.ListenerEndpoint != nil { + if err := d.Set("listener_endpoint", []interface{}{flattenEndpoint(v.ListenerEndpoint)}); err != nil { + return sdkdiag.AppendErrorf(diags, "setting listener_endpoint: %s", err) + } + } else { + d.Set("listener_endpoint", nil) + } + dbSetResourceDataEngineVersionFromInstance(d, v) tags, err := ListTags(ctx, conn, arn) @@ -2585,3 +2616,25 @@ func dbInstanceValidBlueGreenEngines() []string { InstanceEngineMySQL, } } + +func flattenEndpoint(apiObject *rds.Endpoint) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{} + + if v := apiObject.Address; v != nil { + tfMap["address"] = aws.StringValue(v) + } + + if v := apiObject.HostedZoneId; v != nil { + tfMap["hosted_zone_id"] = aws.StringValue(v) + } + + if v := apiObject.Port; v != nil { + tfMap["port"] = aws.Int64Value(v) + } + + return tfMap +} diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 202e22a64ff..feddd6caddd 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -65,6 +65,7 @@ func TestAccRDSInstance_basic(t *testing.T) { resource.TestCheckResourceAttrPair(resourceName, "instance_class", "data.aws_rds_orderable_db_instance.test", "instance_class"), resource.TestCheckResourceAttr(resourceName, "iops", "0"), resource.TestCheckResourceAttr(resourceName, "license_model", "general-public-license"), + resource.TestCheckResourceAttr(resourceName, "listener_endpoint.#", "0"), resource.TestCheckResourceAttrSet(resourceName, "maintenance_window"), resource.TestCheckResourceAttr(resourceName, "max_allocated_storage", "0"), resource.TestCheckResourceAttr(resourceName, "name", "test"), @@ -2827,6 +2828,7 @@ func TestAccRDSInstance_SnapshotIdentifier_multiAZSQLServer(t *testing.T) { testAccCheckInstanceExists(ctx, sourceDbResourceName, &sourceDbInstance), testAccCheckDBSnapshotExists(ctx, snapshotResourceName, &dbSnapshot), testAccCheckInstanceExists(ctx, resourceName, &dbInstance), + resource.TestCheckResourceAttr(resourceName, "listener_endpoint.#", "1"), resource.TestCheckResourceAttr(resourceName, "multi_az", "true"), ), }, diff --git a/website/docs/r/db_instance.html.markdown b/website/docs/r/db_instance.html.markdown index 1bf84969602..f651034e53a 100644 --- a/website/docs/r/db_instance.html.markdown +++ b/website/docs/r/db_instance.html.markdown @@ -309,6 +309,7 @@ in a Route 53 Alias record). * `id` - The RDS instance ID. * `instance_class`- The RDS instance class. * `latest_restorable_time` - The latest time, in UTC [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8), to which a database can be restored with point-in-time restore. +* `listener_endpoint` - Specifies the listener connection endpoint for SQL Server Always On. See [endpoint](#endpoint) below. * `maintenance_window` - The instance maintenance window. * `multi_az` - If the RDS instance is multi AZ enabled. * `name` - The database name. @@ -323,6 +324,12 @@ On Oracle and Microsoft SQL instances the following is exported additionally: * `character_set_name` - The character set (collation) used on Oracle and Microsoft SQL instances. +### Endpoint + +* `address` - Specifies the DNS address of the DB instance. +* `hosted_zone_id` - Specifies the ID that Amazon Route 53 assigns when you create a hosted zone. +* `port` - Specifies the port that the database engine is listening on. + ## Timeouts [Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts):