From 41d48c06c8fbb17d7316ca10ed5092a160c96940 Mon Sep 17 00:00:00 2001 From: cts01586841 Date: Wed, 18 Dec 2024 16:26:25 +0800 Subject: [PATCH] resource/alicloud_db_instance: fix_add_ModifyDBInstanceConfig --- alicloud/resource_alicloud_db_instance.go | 100 +++++++++++++++++- .../resource_alicloud_db_instance_test.go | 76 ++++++++++--- website/docs/r/db_instance.html.markdown | 13 ++- 3 files changed, 171 insertions(+), 18 deletions(-) diff --git a/alicloud/resource_alicloud_db_instance.go b/alicloud/resource_alicloud_db_instance.go index ba8bba6a9825..b8ec33f88483 100644 --- a/alicloud/resource_alicloud_db_instance.go +++ b/alicloud/resource_alicloud_db_instance.go @@ -397,9 +397,26 @@ func resourceAliCloudDBInstance() *schema.Resource { Type: schema.TypeString, Optional: true, DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - return d.Get("engine").(string) != "PostgreSQL" && d.Get("engine").(string) != "MySQL" && d.Get("engine").(string) != "SQLServer" + engine := d.Get("engine").(string) + encryptionKey := d.Get("encryption_key").(string) + if engine != "PostgreSQL" && engine != "MySQL" && engine != "SQLServer" { + return true + } + if engine == "PostgreSQL" { + if encryptionKey == "ServiceKey" && old != "" { + return true + } + if encryptionKey == "disable" && old == "" { + return true + } + } + return false }, }, + "tde_encryption_key": { + Type: schema.TypeString, + Optional: true, + }, "zone_id_slave_a": { Type: schema.TypeString, Optional: true, @@ -606,6 +623,20 @@ func resourceAliCloudDBInstance() *schema.Resource { Optional: true, ValidateFunc: StringInSlice([]string{"Up", "Down", "TempUpgrade", "Serverless"}, false), }, + "pg_bouncer_enabled": { + Type: schema.TypeBool, + Optional: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return d.Get("engine").(string) != "PostgreSQL" + }, + }, + "recovery_model": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return d.Get("engine").(string) != "SQLServer" + }, + }, }, } } @@ -1122,7 +1153,7 @@ func resourceAliCloudDBInstanceUpdate(d *schema.ResourceData, meta interface{}) if v, ok := d.GetOk("role_arn"); ok && v.(string) != "" { request["RoleARN"] = v.(string) } - if v, ok := d.GetOk("encryption_key"); ok && v.(string) != "" { + if v, ok := d.GetOk("tde_encryption_key"); ok && v.(string) != "" { request["EncryptionKey"] = v.(string) if ro, ok := request["RoleARN"].(string); !ok || ro == "" { roleArn, err := findKmsRoleArn(client, v.(string)) @@ -1561,6 +1592,57 @@ func resourceAliCloudDBInstanceUpdate(d *schema.ResourceData, meta interface{}) } } + handleConfigChange := func(configName string, configValue interface{}) error { + action := "ModifyDBInstanceConfig" + request := map[string]interface{}{ + "RegionId": client.RegionId, + "DBInstanceId": d.Id(), + "ConfigName": configName, + "ConfigValue": configValue, + } + response, err := conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2014-08-15"), StringPointer("AK"), nil, request, &runtime) + 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()) + } + return nil + } + if "PostgreSQL" == d.Get("engine").(string) { + if d.HasChange("pg_bouncer_enabled") { + if err := handleConfigChange("pgbouncer", d.Get("pg_bouncer_enabled")); err != nil { + return err + } + } + + if d.HasChange("encryption_key") { + if v, ok := d.GetOk("encryption_key"); ok { + var configValue string + if v.(string) == "disabled" { + configValue = "disabled" + } else { + configValue = v.(string) + } + if err := handleConfigChange("encryptionKey", configValue); err != nil { + return err + } + } + } + + } + + if "SQLServer" == d.Get("engine").(string) { + if d.HasChange("recovery_model") { + if err := handleConfigChange("backup_recovery_model", d.Get("recovery_model")); err != nil { + return err + } + } + } + if !d.IsNewResource() && (d.HasChange("target_minor_version") || d.HasChange("upgrade_db_instance_kernel_version")) { action := "UpgradeDBInstanceKernelVersion" request := map[string]interface{}{ @@ -1659,6 +1741,17 @@ func resourceAliCloudDBInstanceRead(d *schema.ResourceData, meta interface{}) er if err != nil { return WrapError(err) } + if "PostgreSQL" == instance["Engine"] { + DBInstanceEncryptionKey, err := rdsService.DescribeDBInstanceEncryptionKey(d.Id()) + if err != nil { + return WrapError(err) + } + d.Set("encryption_key", "") + if DBInstanceEncryptionKey["EncryptionKey"] != "" { + d.Set("encryption_key", DBInstanceEncryptionKey["EncryptionKey"]) + } + } + describeDBInstanceHAConfigObject, err := rdsService.DescribeDBInstanceHAConfig(d.Id()) hostInstanceInfos := describeDBInstanceHAConfigObject["HostInstanceInfos"].(map[string]interface{})["NodeInfo"].([]interface{}) var nodeId string @@ -1708,6 +1801,7 @@ func resourceAliCloudDBInstanceRead(d *schema.ResourceData, meta interface{}) er d.Set("zone_id", instance["ZoneId"]) d.Set("status", instance["DBInstanceStatus"]) d.Set("create_time", instance["CreationTime"]) + d.Set("pg_bouncer_enabled", instance["PGBouncerEnabled"]) // MySQL Serverless instance query PayType return SERVERLESS, need to be consistent with the participant. payType := instance["PayType"] @@ -1763,6 +1857,8 @@ func resourceAliCloudDBInstanceRead(d *schema.ResourceData, meta interface{}) er } else if len(slaveZones) == 1 { d.Set("zone_id_slave_a", slaveZones[0].(map[string]interface{})["ZoneId"]) } + recoveryModel := instance["Extra"].(map[string]interface{})["RecoveryModel"] + d.Set("recovery_model", recoveryModel) if sqlCollectorPolicy["SQLCollectorStatus"] == "Enable" { d.Set("sql_collector_status", "Enabled") } else { diff --git a/alicloud/resource_alicloud_db_instance_test.go b/alicloud/resource_alicloud_db_instance_test.go index b9258e1e84c6..00d3d5f5afd5 100644 --- a/alicloud/resource_alicloud_db_instance_test.go +++ b/alicloud/resource_alicloud_db_instance_test.go @@ -227,6 +227,8 @@ func TestAccAliCloudRdsDBInstance_Mysql_8_0(t *testing.T) { "db_instance_storage_type": "cloud_ssd", "resource_group_id": "${data.alicloud_resource_manager_resource_groups.default.ids.0}", "db_is_ignore_case": "false", + "tde_status": "Enabled", + "tde_encryption_key": "${alicloud_kms_key.default.id}", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -238,6 +240,7 @@ func TestAccAliCloudRdsDBInstance_Mysql_8_0(t *testing.T) { "auto_upgrade_minor_version": "Auto", "db_instance_storage_type": "cloud_ssd", "resource_group_id": CHECKSET, + "tde_status": "Enabled", }), ), }, @@ -438,7 +441,6 @@ func TestAccAliCloudRdsDBInstance_Mysql_8_0(t *testing.T) { "value": "70", }, }, - "encryption_key": "${alicloud_kms_key.default.id}", "port": "3306", "connection_string_prefix": connectionStringPrefixSecond, }), @@ -492,7 +494,7 @@ func TestAccAliCloudRdsDBInstance_Mysql_8_0(t *testing.T) { ResourceName: resourceId, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"force_restart", "db_is_ignore_case", "parameters", "encryption_key", "security_group_id", "storage_auto_scale", "storage_threshold", "storage_upper_bound"}, + ImportStateVerifyIgnore: []string{"force_restart", "db_is_ignore_case", "parameters", "tde_encryption_key", "security_group_id", "storage_auto_scale", "storage_threshold", "storage_upper_bound"}, }, }, }) @@ -640,8 +642,9 @@ func TestAccAliCloudRdsDBInstance_VpcId(t *testing.T) { }, { Config: testAccConfig(map[string]interface{}{ - "tde_status": "Enabled", - "role_arn": "${data.alicloud_ram_roles.default.roles.0.arn}", + "tde_status": "Enabled", + "role_arn": "${data.alicloud_ram_roles.default.roles.0.arn}", + "tde_encryption_key": "${alicloud_kms_key.default.id}", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -709,7 +712,7 @@ func TestAccAliCloudRdsDBInstance_VpcId(t *testing.T) { ResourceName: resourceId, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"force", "force_restart", "db_is_ignore_case", "tde_status", "sql_collector_status", "role_arn"}, + ImportStateVerifyIgnore: []string{"force", "force_restart", "db_is_ignore_case", "tde_status", "tde_encryption_key", "sql_collector_status", "role_arn"}, }, }, }) @@ -1017,6 +1020,16 @@ func TestAccAliCloudRdsDBInstance_SQLServer(t *testing.T) { }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "recovery_model": "simple", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "recovery_model": "simple", + }), + ), + }, { Config: testAccConfig(map[string]interface{}{ "instance_storage": "50", @@ -1236,6 +1249,7 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_12_0(t *testing.T) { "monitoring_period": "60", "category": "HighAvailability", "target_minor_version": "rds_postgres_1200_20231030", + "encryption_key": "${alicloud_kms_key.default.id}", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -1246,6 +1260,37 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_12_0(t *testing.T) { "db_instance_storage_type": "cloud_essd", "category": "HighAvailability", "target_minor_version": "rds_postgres_1200_20231030", + "encryption_key": CHECKSET, + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "pg_bouncer_enabled": "true", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "pg_bouncer_enabled": "true", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "pg_bouncer_enabled": "false", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "pg_bouncer_enabled": "false", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "encryption_key": "disabled", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "encryption_key": "", }), ), }, @@ -1376,7 +1421,6 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_12_0(t *testing.T) { "vswitch_id": "${local.vswitch_id}", "security_group_ids": []string{}, "monitoring_period": "60", - "encryption_key": "${alicloud_kms_key.default.id}", "category": "HighAvailability", "db_instance_storage_type": "cloud_essd2", "connection_string_prefix": connectionStringPrefixSecond, @@ -1504,6 +1548,7 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_13_0_SSL(t *testing.T) { "db_time_zone": "America/New_York", "connection_string_prefix": "${var.name}", "port": "5999", + "pg_bouncer_enabled": "true", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -1518,6 +1563,7 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_13_0_SSL(t *testing.T) { "port": "5999", "connection_string_prefix": CHECKSET, "instance_name": CHECKSET, + "pg_bouncer_enabled": "true", }), ), }, @@ -1690,7 +1736,6 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_13_0_SSL(t *testing.T) { "vswitch_id": "${local.vswitch_id}", "security_group_ids": []string{}, "monitoring_period": "60", - "encryption_key": "${alicloud_kms_key.default.id}", "ssl_action": "Open", "ca_type": "aliyun", "client_ca_enabled": "1", @@ -1701,6 +1746,7 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_13_0_SSL(t *testing.T) { "replication_acl": "cert", "deletion_protection": "false", "auto_upgrade_minor_version": "Auto", + "encryption_key": "${alicloud_kms_key.default.id}", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -1728,6 +1774,7 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_13_0_SSL(t *testing.T) { "server_key": CHECKSET, "deletion_protection": "false", "auto_upgrade_minor_version": "Auto", + "encryption_key": CHECKSET, }), ), }, @@ -1997,7 +2044,6 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_15_0_Babelfish(t *testing.T) { "vswitch_id": "${local.vswitch_id}", "security_group_ids": []string{}, "monitoring_period": "60", - "encryption_key": "${alicloud_kms_key.default.id}", "ssl_action": "Open", "ca_type": "aliyun", "client_ca_enabled": "1", @@ -2051,7 +2097,7 @@ func TestAccAliCloudRdsDBInstance_PostgreSQL_15_0_Babelfish(t *testing.T) { ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"force_restart", "db_is_ignore_case", "fresh_white_list_readins", "released_keep_policy", "babelfish_config.#", - "client_ca_enabled", "client_crl_enabled", "db_instance_ip_array_name", "encryption_key", "security_group_id", "modify_mode", "security_ip_type", + "client_ca_enabled", "client_crl_enabled", "db_instance_ip_array_name", "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"}, }, @@ -2431,7 +2477,6 @@ func TestAccAliCloudRdsDBInstance_Mysql_8_0_PrePaid(t *testing.T) { "vswitch_id": "${local.vswitch_id}", "monitoring_period": "60", "security_group_ids": "${alicloud_security_group.default.*.id}", - "encryption_key": "${alicloud_kms_key.default.id}", "security_ips": []string{"10.168.1.12", "100.69.7.112"}, "db_time_zone": "America/New_York", "resource_group_id": "${data.alicloud_resource_manager_resource_groups.default.ids.0}", @@ -2452,7 +2497,7 @@ func TestAccAliCloudRdsDBInstance_Mysql_8_0_PrePaid(t *testing.T) { ResourceName: resourceId, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"force_restart", "period", "encryption_key", "db_is_ignore_case"}, + ImportStateVerifyIgnore: []string{"force_restart", "period", "db_is_ignore_case"}, }, { Config: testAccConfig(map[string]interface{}{ @@ -2543,7 +2588,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", "Postpaid", "db_is_ignore_case"}, }, }, }) @@ -3166,6 +3211,7 @@ func TestAccAliCloudRdsDBInstance_SQLServer_2019_ServerlessHA(t *testing.T) { "min_capacity": "2", }, }, + "recovery_model": "simple", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -3179,6 +3225,7 @@ func TestAccAliCloudRdsDBInstance_SQLServer_2019_ServerlessHA(t *testing.T) { "serverless_config.#": "1", "serverless_config.0.max_capacity": "8", "serverless_config.0.min_capacity": "2", + "recovery_model": "simple", }), ), }, @@ -3508,7 +3555,6 @@ func TestAccAliCloudRdsDBInstanceMysql_DBEncryptionKey(t *testing.T) { "instance_name": "${var.name}", "vswitch_id": "${data.alicloud_vswitches.default.ids.0}", "db_instance_storage_type": "cloud_essd", - "encryption_key": "${alicloud_kms_key.default.id}", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -3527,7 +3573,7 @@ func TestAccAliCloudRdsDBInstanceMysql_DBEncryptionKey(t *testing.T) { ResourceName: resourceId, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"force_restart", "period", "encryption_key", "direction", "auto_renew", "auto_renew_period"}, + ImportStateVerifyIgnore: []string{"force_restart", "period", "direction", "auto_renew", "auto_renew_period"}, }, }, }) @@ -3937,7 +3983,7 @@ func TestAccAliCloudRdsDBInstanceMysql_general_essd(t *testing.T) { ResourceName: resourceId, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"force_restart", "period", "encryption_key", "direction", "auto_renew", "auto_renew_period"}, + ImportStateVerifyIgnore: []string{"force_restart", "period", "direction", "auto_renew", "auto_renew_period"}, }, }, }) diff --git a/website/docs/r/db_instance.html.markdown b/website/docs/r/db_instance.html.markdown index 1c949f4721be..42df7bbbf183 100644 --- a/website/docs/r/db_instance.html.markdown +++ b/website/docs/r/db_instance.html.markdown @@ -668,7 +668,14 @@ The following arguments are supported: -> **NOTE:** The attribute `ssl_action` will be ignored when setting `instance_charge_type = "Serverless"` for SQLServer, PostgreSQL or MariaDB. * `ssl_connection_string` - (Optional, Available since v1.198.0) The internal or public endpoint for which the server certificate needs to be created or updated. * `tde_status` - (Optional, Available since 1.90.0) The TDE(Transparent Data Encryption) status. After TDE is turned on, it cannot be turned off. See more [engine and engineVersion limitation](https://www.alibabacloud.com/help/zh/doc-detail/26256.htm). +-> **NOTE:** When creating an instance and enabling disk encryption, you can only use the Key ID; you cannot use the ServiceKey. * `encryption_key` - (Optional, Available since 1.109.0) The key id of the KMS. Used for encrypting a disk if not null. Only for PostgreSQL, MySQL and SQLServer. + When the instance is PostgreSQL, this parameter can be used to enable, modify, and disable cloud disk encryption.Value range: + - ServiceKey: Enable disk encryption using the service-managed key (Default Service CMK) automatically generated by Alibaba Cloud RDS. + - : Use a custom key to enable cloud disk encryption or change the current key. For example: 494c98ce-f2b5-48ab-96ab-36c986b6****. + - disabled: Turn off cloud disk encryption. +-> **NOTE:** This parameter is available when the instance runs MySQL. +* `tde_encryption_key` - (Optional, Available since 1.239.0) The ID of the custom key. * `ca_type` - (Optional, Available since 1.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 @@ -695,7 +702,11 @@ The following arguments are supported: * `ha_config` - (Optional, Available since 1.128.0) The primary/secondary switchover mode of the instance. Default value: Auto. Valid values: - Auto: The system automatically switches over services from the primary to secondary instances in the event of a fault. - Manual: You must manually switch over services from the primary to secondary instances in the event of a fault. - +* `pg_bouncer_enabled`- (Optional, Available since 1.239.0) Modify the PgBouncer feature of the RDS PostgreSQL instance. Valid values: + - true: enable. + - false: disable. +* `recovery_model` - (Optional, Available since 1.239.0) Enable the Simple Recovery Model for an RDS SQL Server Instance.The Simple Recovery Model feature is only supported by the Basic Series of RDS SQL Server instances. Once this feature is enabled, it cannot be disabled.Valid values: + - simple: Enable Simple Recovery. -> **NOTE:** If you set this parameter to Manual, you must specify the ManualHATime parameter. * `manual_ha_time` - (Optional, Available since 1.128.0) The time after when you want to enable automatic primary/secondary switchover. At most, you can set this parameter to 23:59:59 seven days later. Specify the time in the ISO 8601 standard in the yyyy-MM-ddTHH:mm:ssZ format. The time must be in UTC.