From fe0a1af2c8989c030bfeaa8b6e3b7ad284d8f1c3 Mon Sep 17 00:00:00 2001 From: cts01586841 Date: Mon, 20 Apr 2026 14:05:09 +0800 Subject: [PATCH] resource/alicloud_db_instance: improve --- alicloud/resource_alicloud_db_instance.go | 325 +++++++++++++++++- .../resource_alicloud_db_instance_test.go | 99 +++++- website/docs/r/db_instance.html.markdown | 39 +++ 3 files changed, 455 insertions(+), 8 deletions(-) diff --git a/alicloud/resource_alicloud_db_instance.go b/alicloud/resource_alicloud_db_instance.go index 6fd3ff7dc778..3fa00d2e3a62 100644 --- a/alicloud/resource_alicloud_db_instance.go +++ b/alicloud/resource_alicloud_db_instance.go @@ -664,6 +664,60 @@ func resourceAliCloudDBInstance() *schema.Resource { Type: schema.TypeBool, Optional: true, }, + "collect_stat_mode": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: StringInSlice([]string{"Before", "After"}, false), + }, + "time_zone": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "collation": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "force_encryption": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: IntInSlice([]int{0, 1}), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return d.Get("engine").(string) != "SQLServer" + }, + }, + "ssl_certificate": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "ssl_password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "tde_certificate": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "tde_private_key": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "tde_password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "tde_db_name": { + Type: schema.TypeString, + Optional: true, + }, }, } } @@ -1012,6 +1066,81 @@ func resourceAliCloudDBInstanceUpdate(d *schema.ResourceData, meta interface{}) } } + if d.Get("engine").(string) == string(PostgreSQL) && !d.IsNewResource() && d.HasChange("engine_version") { + action := "UpgradeDBInstanceMajorVersionPrecheck" + request := map[string]interface{}{ + "RegionId": client.RegionId, + "DBInstanceId": d.Id(), + "SourceIp": client.SourceIp, + } + if v, ok := d.GetOk("engine_version"); ok && v.(string) != "" { + request["TargetMajorVersion"] = v + } + var response map[string]interface{} + wait := incrementalWait(3*time.Second, 3*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RpcPost("Rds", "2014-08-15", action, nil, request, false) + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + addDebug(action, response, request) + stateConf = BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutCreate), 3*time.Minute, rdsService.RdsDBInstanceStateRefreshFunc(d.Id(), []string{"Deleting"})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + stateConf := BuildStateConf([]string{}, []string{"Success"}, d.Timeout(schema.TimeoutUpdate), 3*time.Second, rdsService.RdsUpgradeMajorVersionRefreshFunc(d.Id(), formatInt(response["TaskId"]), []string{"Failed"})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + action = "UpgradeDBInstanceMajorVersion" + request = map[string]interface{}{ + "RegionId": client.RegionId, + "DBInstanceId": d.Id(), + "SwitchOver": "true", + "UpgradeMode": "inPlaceUpgrade", + "SwitchTimeMode": "Immediate", + "SourceIp": client.SourceIp, + } + if v, ok := d.GetOk("engine_version"); ok && v.(string) != "" { + request["TargetMajorVersion"] = v + } + if v, ok := d.GetOk("instance_charge_type"); ok && v.(string) != "" { + request["PayType"] = v + } + if v, ok := d.GetOk("collect_stat_mode"); ok && v.(string) != "" { + request["CollectStatMode"] = v + } + wait = incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RpcPost("Rds", "2014-08-15", action, nil, request, true) + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, "alicloud_rds_upgrade_db_instance", action, AlibabaCloudSdkGoERROR) + } + stateConf = BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutCreate), 3*time.Minute, rdsService.RdsDBInstanceStateRefreshFunc(d.Id(), []string{"Deleting"})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + } + if d.HasChange("security_ip_mode") && d.Get("security_ip_mode").(string) == SafetyMode { action := "MigrateSecurityIPMode" request := map[string]interface{}{ @@ -1076,7 +1205,105 @@ func resourceAliCloudDBInstanceUpdate(d *schema.ResourceData, meta interface{}) d.SetPartial("sql_collector_config_value") } - if d.HasChange("tde_status") { + if string(SQLServer) == d.Get("engine").(string) && d.HasChange("tde_db_name") { + oldVal, newVal := d.GetChange("tde_db_name") + oldStr := strings.TrimSpace(oldVal.(string)) + newStr := strings.TrimSpace(newVal.(string)) + + oldSet := make(map[string]bool) + if oldStr != "" { + for _, name := range strings.Split(oldStr, ",") { + name = strings.TrimSpace(name) + if name != "" { + oldSet[name] = true + } + } + } + newSet := make(map[string]bool) + if newStr != "" { + for _, name := range strings.Split(newStr, ",") { + name = strings.TrimSpace(name) + if name != "" { + newSet[name] = true + } + } + } + var toDisable []string + for name := range oldSet { + if !newSet[name] { + toDisable = append(toDisable, name) + } + } + var toEnable []string + for name := range newSet { + if !oldSet[name] { + toEnable = append(toEnable, name) + } + } + + if oldStr == "" && newStr != "" { + if v, ok := d.GetOk("tde_certificate"); !ok || v.(string) == "" { + return WrapError(fmt.Errorf("tde_certificate is required when tde_db_name changes from empty to non-empty")) + } + if v, ok := d.GetOk("tde_private_key"); !ok || v.(string) == "" { + return WrapError(fmt.Errorf("tde_private_key is required when tde_db_name changes from empty to non-empty")) + } + if v, ok := d.GetOk("tde_password"); !ok || v.(string) == "" { + return WrapError(fmt.Errorf("tde_password is required when tde_db_name changes from empty to non-empty")) + } + } + + for _, dbName := range toDisable { + action := "ModifyDBInstanceTDE" + request := map[string]interface{}{ + "RegionId": client.RegionId, + "DBInstanceId": d.Id(), + "TDEStatus": "Disabled", + "DBName": dbName, + "SourceIp": client.SourceIp, + } + response, err := client.RpcPost("Rds", "2014-08-15", action, nil, request, false) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + addDebug(action, response, request) + stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 0, rdsService.RdsDBInstanceStateRefreshFunc(d.Id(), []string{"Deleting"})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + } + + for _, dbName := range toEnable { + action := "ModifyDBInstanceTDE" + request := map[string]interface{}{ + "RegionId": client.RegionId, + "DBInstanceId": d.Id(), + "TDEStatus": "Enabled", + "DBName": dbName, + "SourceIp": client.SourceIp, + } + if v, ok := d.GetOk("tde_certificate"); ok && v.(string) != "" { + request["Certificate"] = v.(string) + } + if v, ok := d.GetOk("tde_private_key"); ok && v.(string) != "" { + request["PrivateKey"] = v.(string) + } + if v, ok := d.GetOk("tde_password"); ok && v.(string) != "" { + request["PassWord"] = v.(string) + } + response, err := client.RpcPost("Rds", "2014-08-15", action, nil, request, false) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + addDebug(action, response, request) + stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 0, rdsService.RdsDBInstanceStateRefreshFunc(d.Id(), []string{"Deleting"})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + } + } + + if d.HasChanges("tde_status") { action := "ModifyDBInstanceTDE" request := map[string]interface{}{ "RegionId": client.RegionId, @@ -1261,7 +1488,7 @@ func resourceAliCloudDBInstanceUpdate(d *schema.ResourceData, meta interface{}) } } - if d.HasChanges("ssl_action", "ssl_connection_string") { + if d.HasChanges("ssl_action", "ssl_connection_string", "force_encryption") { action := "ModifyDBInstanceSSL" request := map[string]interface{}{ "DBInstanceId": d.Id(), @@ -1354,6 +1581,22 @@ func resourceAliCloudDBInstanceUpdate(d *schema.ResourceData, meta interface{}) } } + if d.Get("engine").(string) == "SQLServer" { + if v, ok := d.GetOkExists("force_encryption"); ok { + request["ForceEncryption"] = v.(int) + } + if d.HasChange("ssl_certificate") { + if v, ok := d.GetOk("ssl_certificate"); ok && v.(string) != "" { + request["Certificate"] = v.(string) + } + } + if d.HasChange("ssl_password") { + if v, ok := d.GetOk("ssl_password"); ok && v.(string) != "" { + request["PassWord"] = v.(string) + } + } + } + request["ConnectionString"] = instance["ConnectionString"] if d.HasChange("ssl_connection_string") { if v, ok := d.GetOk("ssl_connection_string"); ok && v.(string) != "" { @@ -1748,6 +1991,51 @@ func resourceAliCloudDBInstanceUpdate(d *schema.ResourceData, meta interface{}) } } + if d.HasChange("time_zone") || d.HasChange("collation") { + stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, rdsService.RdsDBInstanceStateRefreshFunc(d.Id(), []string{"Deleting"})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + + action := "ModifyCollationTimeZone" + request := map[string]interface{}{ + "DBInstanceId": d.Id(), + "RegionId": client.RegionId, + "SourceIp": client.SourceIp, + } + + if v, ok := d.GetOk("time_zone"); ok && v.(string) != "" { + request["Timezone"] = v + } + if v, ok := d.GetOk("collation"); ok && v.(string) != "" { + request["Collation"] = v + } + + var response map[string]interface{} + wait := incrementalWait(3*time.Second, 3*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RpcPost("Rds", "2014-08-15", action, nil, request, false) + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + addDebug(action, response, request) + + stateConf = BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, rdsService.RdsDBInstanceStateRefreshFunc(d.Id(), []string{"Deleting"})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + } + if !d.IsNewResource() && (d.HasChange("target_minor_version") || d.HasChange("upgrade_db_instance_kernel_version")) { action := "UpgradeDBInstanceKernelVersion" request := map[string]interface{}{ @@ -1994,6 +2282,12 @@ func resourceAliCloudDBInstanceRead(d *schema.ResourceData, meta interface{}) er if err = rdsService.SetTimeZone(d); err != nil { return WrapError(err) } + if v, ok := instance["TimeZone"]; ok && v != nil && v != "" { + d.Set("time_zone", v) + } + if v, ok := instance["Collation"]; ok && v != nil && v != "" { + d.Set("collation", v) + } if instance["PayType"] == string(Prepaid) { action := "DescribeInstanceAutoRenewalAttribute" request := map[string]interface{}{ @@ -2056,6 +2350,9 @@ func resourceAliCloudDBInstanceRead(d *schema.ResourceData, meta interface{}) er d.Set("acl", sslAction["ACL"]) d.Set("replication_acl", sslAction["ReplicationACL"]) d.Set("ssl_connection_string", sslAction["ConnectionString"]) + if v, ok := sslAction["ForceEncryption"]; ok && v != nil { + d.Set("force_encryption", v) + } //When the instance schema is docker on ECS, TDE encryption is not supported, so the query is not executed. if kindCode, ok := instance["kindCode"]; ok && kindCode != "3" { @@ -2064,6 +2361,22 @@ func resourceAliCloudDBInstanceRead(d *schema.ResourceData, meta interface{}) er return WrapError(err) } d.Set("tde_status", tdeInfo["TDEStatus"]) + if databases, ok := tdeInfo["Databases"]; ok && databases != nil { + if dbMap, ok := databases.(map[string]interface{}); ok { + if dbList, ok := dbMap["Database"]; ok && dbList != nil { + var enabledDbNames []string + for _, db := range dbList.([]interface{}) { + dbItem := db.(map[string]interface{}) + if dbItem["TDEStatus"] == "Enabled" { + if dbName, ok := dbItem["DBName"].(string); ok && dbName != "" { + enabledDbNames = append(enabledDbNames, dbName) + } + } + } + d.Set("tde_db_name", strings.Join(enabledDbNames, ",")) + } + } + } } res, err := rdsService.DescribeHASwitchConfig(d.Id()) if err != nil { @@ -2192,6 +2505,14 @@ func buildDBCreateRequest(d *schema.ResourceData, meta interface{}) (map[string] if v, ok := d.GetOk("optimized_writes"); ok && v.(string) != "" { request["OptimizedWrites"] = v } + if v, ok := d.GetOk("tags"); ok { + count := 1 + for key, value := range v.(map[string]interface{}) { + request[fmt.Sprintf("Tag.%d.Key", count)] = key + request[fmt.Sprintf("Tag.%d.Value", count)] = value + count++ + } + } if request["Engine"] == "MySQL" || request["Engine"] == "PostgreSQL" || request["Engine"] == "SQLServer" { if v, ok := d.GetOk("role_arn"); ok && v.(string) != "" { diff --git a/alicloud/resource_alicloud_db_instance_test.go b/alicloud/resource_alicloud_db_instance_test.go index ff1887516045..20f15199f681 100644 --- a/alicloud/resource_alicloud_db_instance_test.go +++ b/alicloud/resource_alicloud_db_instance_test.go @@ -25,7 +25,7 @@ func init() { /* "ssl_connection_string" There may be issues with circular dependencies, which cannot be tested in the case -"server_key","server_cert" These two parameters need to be generated offline and cannot be generated in online tests +"server_key","server_cert","ssl_certificate","ssl_password","tde_certificate","tde_private_key","tde_password","tde_db_name" These two parameters need to be generated offline and cannot be generated in online tests */ func testSweepDBInstances(region string) error { @@ -987,6 +987,8 @@ func TestAccAliCloudRdsDBInstance_SQLServer(t *testing.T) { "vswitch_id": "${local.vswitch_id}", "monitoring_period": "60", "category": "HighAvailability", + "time_zone": "China Standard Time", + "collation": "Chinese_PRC_CI_AS", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -996,6 +998,8 @@ func TestAccAliCloudRdsDBInstance_SQLServer(t *testing.T) { "instance_storage": CHECKSET, "db_instance_storage_type": "cloud_essd", "category": "HighAvailability", + "time_zone": "China Standard Time", + "collation": "Chinese_PRC_CI_AS", }), ), }, @@ -1021,7 +1025,7 @@ func TestAccAliCloudRdsDBInstance_SQLServer(t *testing.T) { }, { Config: testAccConfig(map[string]interface{}{ - "instance_type": "${data.alicloud_db_instance_classes.default.instance_classes.1.instance_class}", + "instance_type": "mssql.x4.medium.s2", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -1088,6 +1092,42 @@ func TestAccAliCloudRdsDBInstance_SQLServer(t *testing.T) { }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "collation": "SQL_Latin1_General_CP1_CI_AS", + "time_zone": "UTC", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "collation": "SQL_Latin1_General_CP1_CI_AS", + "time_zone": "UTC", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "ssl_action": "Open", + "force_encryption": "1", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "ssl_action": "Open", + "force_encryption": "1", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "ssl_action": "Close", + "force_encryption": "0", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "ssl_action": "Close", + "force_encryption": "0", + }), + ), + }, { Config: testAccConfig(map[string]interface{}{ "engine": "SQLServer", @@ -2033,7 +2073,7 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_15_0_Babelfish(t *testing.T) { ResourceName: resourceId, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"force_restart", "db_is_ignore_case", "fresh_white_list_readins", "released_keep_policy", "babelfish_config.#", + ImportStateVerifyIgnore: []string{"force_restart", "db_is_ignore_case", "fresh_white_list_readins", "released_keep_policy", "client_ca_enabled", "client_crl_enabled", "db_instance_ip_array_name", "encryption_key", "security_group_id", "modify_mode", "security_ip_type", "whitelist_network_type", "babelfish_config.2289427611.babelfish_enabled", "babelfish_config.2289427611.master_user_password", "babelfish_config.2289427611.master_username", "babelfish_config.2289427611.migration_mode"}, @@ -2534,7 +2574,7 @@ func TestAccAliCloudRdsDBInstance_Mysql_8_0_Cluster(t *testing.T) { ResourceName: resourceId, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"force_restart", "Postpaid", "encryption_key", "db_is_ignore_case"}, + ImportStateVerifyIgnore: []string{"force_restart", "encryption_key", "db_is_ignore_case"}, }, }, }) @@ -3110,6 +3150,8 @@ resource "alicloud_security_group" "default" { } func TestAccAliCloudRdsDBInstance_SQLServer_2019_ServerlessHA(t *testing.T) { + t.Skipf("Skipping test: ssl_certificate, ssl_password, tde_certificate, tde_private_key, tde_password, tde_db_name require customer-generated certificates offline") + var instance map[string]interface{} var ips []map[string]interface{} @@ -3242,7 +3284,9 @@ func TestAccAliCloudRdsDBInstance_SQLServer_2019_ServerlessHA(t *testing.T) { // ssl_action is ignored for SQLServer { Config: testAccConfig(map[string]interface{}{ - "ssl_action": "Open", + "ssl_action": "Open", + "ssl_certificate": "oss-cn-beijing.aliyuncs.com:sjcbeijing:rdsTest.pfx", + "ssl_password": "123456", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{}), @@ -3258,6 +3302,38 @@ func TestAccAliCloudRdsDBInstance_SQLServer_2019_ServerlessHA(t *testing.T) { }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "tde_db_name": "test01", + "tde_password": "cMr2O6BnU3XFMlHu86/DHbOlbGFgo5prUrGCbcARI/E=", + "tde_private_key": "oss-cn-beijing.aliyuncs.com:sjcbeijing:rdsTest.pvk", + "tde_certificate": "oss-cn-beijing.aliyuncs.com:sjcbeijing:rdsTest.cer", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "tde_db_name": "test01", + "tde_password": "cMr2O6BnU3XFMlHu86/DHbOlbGFgo5prUrGCbcARI/E=", + "tde_private_key": "oss-cn-beijing.aliyuncs.com:sjcbeijing:rdsTest.pvk", + "tde_certificate": "oss-cn-beijing.aliyuncs.com:sjcbeijing:rdsTest.cer", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "tde_db_name": "test02", + "tde_password": "cMr2O6BnU3XFMlHu86/DHbOlbGFgo5prUrGCbcARI/E=", + "tde_private_key": "oss-cn-beijing.aliyuncs.com:sjcbeijing:rdsTest.pvk", + "tde_certificate": "oss-cn-beijing.aliyuncs.com:sjcbeijing:rdsTest.cer", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "tde_db_name": "test02", + "tde_password": "cMr2O6BnU3XFMlHu86/DHbOlbGFgo5prUrGCbcARI/E=", + "tde_private_key": "oss-cn-beijing.aliyuncs.com:sjcbeijing:rdsTest.pvk", + "tde_certificate": "oss-cn-beijing.aliyuncs.com:sjcbeijing:rdsTest.cer", + }), + ), + }, { ResourceName: resourceId, ImportState: true, @@ -4070,11 +4146,22 @@ func TestAccAliCloudRdsDBInstancePostgreSQL(t *testing.T) { }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "engine_version": "18.0", + "collect_stat_mode": "Before", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "engine_version": "18.0", + }), + ), + }, { ResourceName: resourceId, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"force_restart", "tde_encryption_key"}, + ImportStateVerifyIgnore: []string{"force_restart", "tde_encryption_key", "collect_stat_mode"}, }, }, }) diff --git a/website/docs/r/db_instance.html.markdown b/website/docs/r/db_instance.html.markdown index e79eece3f080..e7868ea33443 100644 --- a/website/docs/r/db_instance.html.markdown +++ b/website/docs/r/db_instance.html.markdown @@ -703,6 +703,45 @@ The following arguments are supported: * `ca_type` - (Optional, Available since v1.124.1) The type of the server certificate. This parameter is supported only when the instance runs PostgreSQL or MySQL with standard or enhanced SSDs. If you set the SSLEnabled parameter to 1, the default value of this parameter is aliyun. **NOTE:** From version 1.231.0, `ca_type` start support `MySQL` engine. Value range: - aliyun: a cloud certificate - custom: a custom certificate +* `collect_stat_mode` - (Optional, Available since v1.277.0) Specify the point in time at which the system collects the statistics of the instance. + - Before: The system collects the statistics of the instance before the switchover to ensure service stability. If the instance contains a large amount of data, the upgrade may require a long period of time. + - After: The system collects the statistics of the instance after the switchover to accelerate the upgrade. After the upgrade, if you access tables for which no statistics are generated, the query plans may be inaccurate, and your database service may be unavailable during peak hours. + + -> **NOTE:** If you set the SwitchOver parameter to false, the value Before specifies that the system collects the statistics of the instance before the instance starts to process read and write requests, and the value After specifies that the system collects the statistics of the instance after the instance starts to process read and write requests. + +* `collation` - (Optional, Available since v1.277.0) The character set collation of the instance. By default, the system does not modify the character set collation of the instance. Valid values: + - `Chinese_PRC_CI_AS` + - `Chinese_PRC_CS_AS` + - `Chinese_PRC_BIN` + - `Latin1_General_CI_AS` + - `Latin1_General_CS_AS` + - `SQL_Latin1_General_CP1_CI_AS` + - `SQL_Latin1_General_CP1_CS_AS` + - `Japanese_CI_AS` + - `Japanese_CS_AS` + - `Chinese_Taiwan_Stroke_CI_AS` + - `Chinese_Taiwan_Stroke_CS_AS` + + -> **NOTE:** The default character set collation of the instance is Chinese_PRC_CI_AS. You must specify one of the Collation and Timezone parameters. + +* `time_zone` - (Optional, Available since v1.277.0) The time zone of the instance. By default, the system does not modify the time zone. + + -> **NOTE:** The default time zone of the instance is China Standard Time. You must specify one of the Collation and Timezone parameters. + +* `force_encryption` - (Optional, Available since v1.277.0) Specifies whether to enable the forceful SSL encryption feature. This parameter is supported only for ApsaraDB RDS for SQL Server instances.Valid values: + - 1: enables the feature. + - 0: disables the feature. +* `ssl_certificate` -(Optional, Available in 1.277.0) The custom certificate. + - Public endpoint: oss-.aliyuncs.com::. + - Internal endpoint: oss--internal.aliyuncs.com::. +* `ssl_password` -(Optional, Available in 1.277.0) The password of the certificate. +* `tde_private_key` -(Optional, Available in 1.277.0) The file that contains the private key of the certificate.. +* `tde_certificate` -(Optional, Available in 1.277.0) The file that contains the certificate.. +* `tde_password` -(Optional, Available in 1.277.0) The password of the certificate. +* `tde_db_name` -(Optional, Available in 1.277.0) The name of the database for which you want to enable TDE. You can specify up to 50 database names in a single request. If you specify multiple database names, separate the database names with commas (,). + + -> **NOTE:** This parameter is available and must be specified only when the instance runs SQL Server 2019 SE or an Enterprise Edition of SQL Server. + * `server_cert` - (Optional, Available since v1.124.1) The content of the server certificate. This parameter is supported only when the instance runs PostgreSQL or MySQL with standard or enhanced SSDs. If you set the CAType parameter to custom, you must also specify this parameter. **NOTE:** From version 1.231.0, `server_cert` start support `MySQL` engine. * `server_key` - (Optional, Available since v1.124.1) The private key of the server certificate. This parameter is supported only when the instance runs PostgreSQL or MySQL with standard or enhanced SSDs. If you set the CAType parameter to custom, you must also specify this parameter. **NOTE:** From version 1.231.0, `server_key` start support `MySQL` engine. * `client_ca_enabled` - (Optional, Available since v1.124.1) Specifies whether to enable the public key of the CA that issues client certificates. This parameter is supported only when the instance runs PostgreSQL with standard or enhanced SSDs. Valid values: