func resourceAliCloudDBInstance()

in alicloud/resource_alicloud_db_instance.go [22:668]


func resourceAliCloudDBInstance() *schema.Resource {
	return &schema.Resource{
		Create: resourceAliCloudDBInstanceCreate,
		Read:   resourceAliCloudDBInstanceRead,
		Update: resourceAliCloudDBInstanceUpdate,
		Delete: resourceAliCloudDBInstanceDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Timeouts: &schema.ResourceTimeout{
			Create: schema.DefaultTimeout(50 * time.Minute),
			Update: schema.DefaultTimeout(30 * time.Minute),
			Delete: schema.DefaultTimeout(30 * time.Minute),
		},

		Schema: map[string]*schema.Schema{
			"engine": {
				Type:     schema.TypeString,
				ForceNew: true,
				Required: true,
			},
			"engine_version": {
				Type: schema.TypeString,
				// Remove this limitation and refer to https://www.alibabacloud.com/help/doc-detail/26228.htm each time
				//ValidateFunc: validateAllowedStringValue([]string{"5.5", "5.6", "5.7", "2008r2", "2012", "9.4", "9.3", "10.0"}),
				Required: true,
			},
			"instance_type": {
				Type:     schema.TypeString,
				Required: true,
			},

			"instance_storage": {
				Type:     schema.TypeInt,
				Required: true,
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					if v, ok := d.GetOk("storage_auto_scale"); ok && v.(string) == "Enable" && old != "" && new != "" && old != new {
						return true
					}
					if v, ok := d.GetOk("instance_charge_type"); ok && v.(string) == "Serverless" && old != "" && new != "" && old != new {
						return true
					}
					return false
				},
			},

			"instance_charge_type": {
				Type:         schema.TypeString,
				ValidateFunc: StringInSlice([]string{string(Postpaid), string(Prepaid), string(Serverless)}, false),
				Optional:     true,
				Default:      Postpaid,
			},
			"period": {
				Type:             schema.TypeInt,
				ValidateFunc:     IntInSlice([]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 24, 36}),
				Optional:         true,
				DiffSuppressFunc: PostPaidDiffSuppressFunc,
			},
			"monitoring_period": {
				Type:         schema.TypeInt,
				ValidateFunc: IntInSlice([]int{5, 10, 60, 300}),
				Optional:     true,
				Computed:     true,
			},
			"auto_renew": {
				Type:             schema.TypeBool,
				Optional:         true,
				Default:          false,
				DiffSuppressFunc: PostPaidDiffSuppressFunc,
			},
			"auto_renew_period": {
				Type:             schema.TypeInt,
				ValidateFunc:     IntBetween(1, 12),
				Optional:         true,
				Default:          1,
				DiffSuppressFunc: PostPaidAndRenewDiffSuppressFunc,
			},
			"force": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: StringInSlice([]string{"Yes", "No"}, false),
			},
			"node_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"zone_id": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Computed: true,
			},

			"db_time_zone": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Computed: true,
			},

			"vswitch_id": {
				Type:     schema.TypeString,
				ForceNew: true,
				Optional: true,
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					// If it is a new resource, do not suppress.
					if d.Id() == "" {
						return false
					}
					// If it is not a new resource and it is a multi-zone deployment, it needs to be suppressed.
					return len(strings.Split(new, ",")) > 1
				},
			},
			"private_ip_address": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"instance_name": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: StringLenBetween(2, 256),
			},

			"connection_string": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"connection_string_prefix": {
				Type:     schema.TypeString,
				Optional: true,
				//ValidateFunc: StringLenBetween(8, 64),
				Computed: true,
			},

			"port": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"security_ips": {
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Computed: true,
				Optional: true,
			},
			"db_instance_ip_array_name": {
				Type:             schema.TypeString,
				Optional:         true,
				DiffSuppressFunc: securityIpsDiffSuppressFunc,
			},
			"db_instance_ip_array_attribute": {
				Type:             schema.TypeString,
				Optional:         true,
				DiffSuppressFunc: securityIpsDiffSuppressFunc,
			},
			"db_instance_type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"security_ip_type": {
				Type:             schema.TypeString,
				Optional:         true,
				DiffSuppressFunc: securityIpsDiffSuppressFunc,
			},
			"whitelist_network_type": {
				Type:             schema.TypeString,
				Optional:         true,
				ValidateFunc:     StringInSlice([]string{"Classic", "VPC", "MIX"}, false),
				DiffSuppressFunc: securityIpsDiffSuppressFunc,
			},
			"modify_mode": {
				Type:             schema.TypeString,
				Optional:         true,
				ValidateFunc:     StringInSlice([]string{"Cover", "Append", "Delete"}, false),
				DiffSuppressFunc: securityIpsDiffSuppressFunc,
			},
			"security_group_id": {
				Type:          schema.TypeString,
				Optional:      true,
				Computed:      true,
				ConflictsWith: []string{"security_group_ids"},
				Deprecated:    "Attribute `security_group_id` has been deprecated from 1.69.0 and use `security_group_ids` instead.",
			},
			"security_group_ids": {
				Type:     schema.TypeSet,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Computed: true,
				Optional: true,
			},
			"security_ip_mode": {
				Type:         schema.TypeString,
				ValidateFunc: StringInSlice([]string{NormalMode, SafetyMode}, false),
				Optional:     true,
				Default:      NormalMode,
			},

			"parameters": {
				Type: schema.TypeSet,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"name": {
							Type:     schema.TypeString,
							Required: true,
						},
						"value": {
							Type:     schema.TypeString,
							Required: true,
						},
					},
				},
				Set:      parameterToHash,
				Optional: true,
				Computed: true,
			},
			"pg_hba_conf": {
				Type: schema.TypeSet,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"type": {
							Type:     schema.TypeString,
							Required: true,
						},
						"mask": {
							Type:     schema.TypeString,
							Optional: true,
							// if attribute contains Optional feature, need to add Default: "", otherwise when terraform plan is executed, unmodified items wil detect differences.
							Default: "",
						},
						"database": {
							Type:     schema.TypeString,
							Required: true,
						},
						"priority_id": {
							Type:     schema.TypeInt,
							Required: true,
						},
						"address": {
							Type:     schema.TypeString,
							Required: true,
						},
						"user": {
							Type:     schema.TypeString,
							Required: true,
						},
						"method": {
							Type:     schema.TypeString,
							Required: true,
						},
						"option": {
							Type:     schema.TypeString,
							Optional: true,
							Default:  "",
						},
					},
				},
				Optional: true,
				Computed: true,
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					return d.Get("engine").(string) != string(PostgreSQL)
				},
			},
			"force_restart": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"tags": tagsSchema(),
			"babelfish_config": {
				Type: schema.TypeSet,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"babelfish_enabled": {
							Type:     schema.TypeString,
							Required: true,
							ForceNew: true,
						},
						"migration_mode": {
							Type:         schema.TypeString,
							Required:     true,
							ForceNew:     true,
							ValidateFunc: StringInSlice([]string{"single-db", "multi-db"}, false),
						},
						"master_username": {
							Type:     schema.TypeString,
							Required: true,
							ForceNew: true,
						},
						"master_user_password": {
							Type:     schema.TypeString,
							Required: true,
							ForceNew: true,
						},
					},
				},
				Optional: true,
				ForceNew: true,
				Computed: true,
			},
			"babelfish_port": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"maintain_time": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			// Default to Manual
			"auto_upgrade_minor_version": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ValidateFunc: StringInSlice([]string{"Auto", "Manual"}, false),
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					return d.Get("engine").(string) != "MySQL" && d.Get("engine").(string) != "PostgreSQL"
				},
			},
			"db_instance_storage_type": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ValidateFunc: StringInSlice([]string{"local_ssd", "cloud_ssd", "cloud_essd", "cloud_essd2", "cloud_essd3", "general_essd"}, false),
			},
			"sql_collector_status": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: StringInSlice([]string{"Enabled", "Disabled"}, false),
				Computed:     true,
			},
			"sql_collector_config_value": {
				Type:         schema.TypeInt,
				Optional:     true,
				ValidateFunc: IntInSlice([]int{30, 180, 365, 1095, 1825}),
				Default:      30,
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					if v, ok := d.GetOk("sql_collector_status"); ok && strings.ToLower(v.(string)) == "enabled" {
						return false
					}
					return true
				},
			},
			"resource_group_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"ssl_action": {
				Type:         schema.TypeString,
				ValidateFunc: StringInSlice([]string{"Open", "Close", "Update"}, false),
				Optional:     true,
				Computed:     true,
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					// currently, only mysql serverless support setting ssl_action
					return d.Get("instance_charge_type").(string) == "Serverless" && d.Get("engine").(string) != "MySQL"
				},
			},
			"ssl_connection_string": {
				Type:             schema.TypeString,
				Optional:         true,
				Computed:         true,
				DiffSuppressFunc: sslActionDiffSuppressFunc,
			},
			"tde_status": {
				Type:         schema.TypeString,
				ValidateFunc: StringInSlice([]string{"Enabled", "Disabled"}, false),
				Optional:     true,
				Computed:     true,
			},
			"ssl_status": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"encryption_key": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					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 == "disabled" && old == "" {
							return true
						}
					}
					return false
				},
			},
			"tde_encryption_key": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"zone_id_slave_a": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
			"zone_id_slave_b": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
			"ca_type": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"server_cert": {
				Type:      schema.TypeString,
				Optional:  true,
				Computed:  true,
				Sensitive: true,
			},
			"server_key": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"client_ca_enabled": {
				Type:     schema.TypeInt,
				Optional: true,
			},
			"client_ca_cert": {
				Type:      schema.TypeString,
				Optional:  true,
				Sensitive: true,
			},
			"client_crl_enabled": {
				Type:     schema.TypeInt,
				Optional: true,
			},
			"client_cert_revocation_list": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"acl": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"replication_acl": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"upgrade_db_instance_kernel_version": {
				Type:       schema.TypeBool,
				Optional:   true,
				Deprecated: "Attribute `upgrade_db_instance_kernel_version` has been deprecated from 1.198.0 and use `target_minor_version` instead.",
			},
			"upgrade_time": {
				Type:             schema.TypeString,
				Optional:         true,
				ValidateFunc:     StringInSlice([]string{"Immediate", "MaintainTime", "SpecifyTime"}, false),
				DiffSuppressFunc: kernelSmallVersionDiffSuppressFunc,
			},
			"switch_time": {
				Type:             schema.TypeString,
				Optional:         true,
				DiffSuppressFunc: kernelSmallVersionDiffSuppressFunc,
			},
			"target_minor_version": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"db_param_group_id": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"storage_auto_scale": {
				Type:         schema.TypeString,
				ValidateFunc: StringInSlice([]string{"Enable", "Disable"}, false),
				Optional:     true,
			},
			"storage_threshold": {
				Type:             schema.TypeInt,
				ValidateFunc:     IntInSlice([]int{0, 10, 20, 30, 40, 50}),
				DiffSuppressFunc: StorageAutoScaleDiffSuppressFunc,
				Optional:         true,
			},
			"storage_upper_bound": {
				Type:             schema.TypeInt,
				ValidateFunc:     IntAtLeast(0),
				DiffSuppressFunc: StorageAutoScaleDiffSuppressFunc,
				Optional:         true,
			},
			"ha_config": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ValidateFunc: StringInSlice([]string{"Auto", "Manual"}, false),
			},
			"manual_ha_time": {
				Type:     schema.TypeString,
				Optional: true,
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					if v, ok := d.GetOk("ha_config"); ok && v.(string) == "Manual" {
						return false
					}
					return true
				},
			},
			"released_keep_policy": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: StringInSlice([]string{"None", "Lastest", "All"}, false),
			},
			"fresh_white_list_readins": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"deletion_protection": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"db_is_ignore_case": {
				Type:     schema.TypeBool,
				Optional: true,
				Computed: true,
			},
			"tcp_connection_type": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ValidateFunc: StringInSlice([]string{"SHORT", "LONG"}, false),
			},
			"vpc_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
			"category": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ValidateFunc: StringInSlice([]string{"Basic", "HighAvailability", "AlwaysOn", "Finance", "cluster", "serverless_basic", "serverless_standard", "serverless_ha"}, false),
			},
			"effective_time": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: StringInSlice([]string{"Immediate", "MaintainTime"}, false),
			},
			"status": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"create_time": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"serverless_config": {
				Type:     schema.TypeList,
				Optional: true,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"max_capacity": {
							Type:     schema.TypeFloat,
							Required: true,
						},
						"min_capacity": {
							Type:     schema.TypeFloat,
							Required: true,
						},
						"auto_pause": {
							Type:     schema.TypeBool,
							Optional: true,
						},
						"switch_force": {
							Type:     schema.TypeBool,
							Optional: true,
						},
					},
				},
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					if v, ok := d.GetOk("instance_charge_type"); ok && v.(string) != "Serverless" {
						return true
					}
					return false
				},
			},
			"role_arn": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Computed: true,
			},
			"direction": {
				Type:         schema.TypeString,
				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,
				Computed: true,
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					return d.Get("engine").(string) != "SQLServer"
				},
			},
			"bursting_enabled": {
				Type:     schema.TypeBool,
				Optional: true,
			},
			"optimized_writes": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ValidateFunc: StringInSlice([]string{"optimized", "none"}, false),
				DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
					optimizedWrites := d.Get("optimized_writes").(string)
					if optimizedWrites == "optimized" && old == "{\"optimized_writes\":true,\"init_optimized_writes\":true}" {
						return true
					}
					if optimizedWrites == "none" && old == "{\"optimized_writes\":false,\"init_optimized_writes\":true}" {
						return true
					}
					return false
				},
			},
		},
	}
}