From b9f918af14b4eba1146e8d7d9a818bd502a1415d Mon Sep 17 00:00:00 2001 From: Kagashino Date: Wed, 30 Mar 2022 19:17:01 +0800 Subject: [PATCH] feat: as - support spot and prepaid charge type --- tencentcloud/resource_tc_as_scaling_config.go | 110 +++++++++++++++++- .../resource_tc_as_scaling_config_test.go | 73 ++++++++++++ .../docs/r/as_scaling_config.html.markdown | 18 +++ 3 files changed, 199 insertions(+), 2 deletions(-) diff --git a/tencentcloud/resource_tc_as_scaling_config.go b/tencentcloud/resource_tc_as_scaling_config.go index 30a92ae4f2..722d275da6 100644 --- a/tencentcloud/resource_tc_as_scaling_config.go +++ b/tencentcloud/resource_tc_as_scaling_config.go @@ -31,6 +31,18 @@ resource "tencentcloud_as_scaling_config" "launch_configuration" { } ``` +Using SPOT charge type +``` +resource "tencentcloud_as_scaling_config" "launch_configuration" { + configuration_name = "launch-configuration" + image_id = "img-9qabwvbn" + instance_types = ["SA1.SMALL1"] + instance_charge_type = "SPOTPAID" + spot_instance_type = "one-time" + spot_max_price = "1000" +} +``` + Import AutoScaling Configuration can be imported using the id, e.g. @@ -135,6 +147,37 @@ func resourceTencentCloudAsScalingConfig() *schema.Resource { }, }, }, + // payment + "instance_charge_type": { + Type: schema.TypeString, + Optional: true, + Description: "Charge type of instance. Valid values are `PREPAID`, `POSTPAID_BY_HOUR`, `SPOTPAID`. The default is `POSTPAID_BY_HOUR`. NOTE: `SPOTPAID` instance must set `spot_instance_type` and `spot_max_price` at the same time.", + }, + "instance_charge_type_prepaid_period": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validateAllowedIntValue(CVM_PREPAID_PERIOD), + Description: "The tenancy (in month) of the prepaid instance, NOTE: it only works when instance_charge_type is set to `PREPAID`. Valid values are `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `24`, `36`.", + }, + "instance_charge_type_prepaid_renew_flag": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validateAllowedStringValue(CVM_PREPAID_RENEW_FLAG), + Description: "Auto renewal flag. Valid values: `NOTIFY_AND_AUTO_RENEW`: notify upon expiration and renew automatically, `NOTIFY_AND_MANUAL_RENEW`: notify upon expiration but do not renew automatically, `DISABLE_NOTIFY_AND_MANUAL_RENEW`: neither notify upon expiration nor renew automatically. Default value: `NOTIFY_AND_MANUAL_RENEW`. If this parameter is specified as `NOTIFY_AND_AUTO_RENEW`, the instance will be automatically renewed on a monthly basis if the account balance is sufficient. NOTE: it only works when instance_charge_type is set to `PREPAID`.", + }, + "spot_instance_type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateAllowedStringValue([]string{"one-time"}), + Description: "Type of spot instance, only support `one-time` now. Note: it only works when instance_charge_type is set to `SPOTPAID`.", + }, + "spot_max_price": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateStringNumber, + Description: "Max price of a spot instance, is the format of decimal string, for example \"0.50\". Note: it only works when instance_charge_type is set to `SPOTPAID`.", + }, "internet_charge_type": { Type: schema.TypeString, Optional: true, @@ -362,7 +405,32 @@ func resourceTencentCloudAsScalingConfigCreate(d *schema.ResourceData, meta inte request.UserData = helper.String(v.(string)) } - chargeType := INSTANCE_CHARGE_TYPE_POSTPAID + chargeType, ok := d.Get("instance_charge_type").(string) + if !ok || chargeType == "" { + chargeType = INSTANCE_CHARGE_TYPE_POSTPAID + } + + if chargeType == INSTANCE_CHARGE_TYPE_SPOTPAID { + spotMaxPrice := d.Get("spot_max_price").(string) + spotInstanceType := d.Get("spot_instance_type").(string) + request.InstanceMarketOptions = &as.InstanceMarketOptionsRequest{ + MarketType: helper.String("spot"), + SpotOptions: &as.SpotMarketOptions{ + MaxPrice: &spotMaxPrice, + SpotInstanceType: &spotInstanceType, + }, + } + } + + if chargeType == INSTANCE_CHARGE_TYPE_PREPAID { + period := d.Get("instance_charge_type_prepaid_period").(int) + renewFlag := d.Get("instance_charge_type_prepaid_renew_flag").(string) + request.InstanceChargePrepaid = &as.InstanceChargePrepaid{ + Period: helper.IntInt64(period), + RenewFlag: &renewFlag, + } + } + request.InstanceChargeType = &chargeType if v, ok := d.GetOk("instance_types_check_policy"); ok { @@ -480,6 +548,19 @@ func resourceTencentCloudAsScalingConfigRead(d *schema.ResourceData, meta interf if config.SystemDisk.DiskType != nil { _ = d.Set("system_disk_type", *config.SystemDisk.DiskType) } + + if _, ok := d.GetOk("instance_charge_type"); ok || *config.InstanceChargeType != INSTANCE_CHARGE_TYPE_POSTPAID { + _ = d.Set("instance_charge_type", *config.InstanceChargeType) + } + + if config.InstanceMarketOptions != nil && config.InstanceMarketOptions.SpotOptions != nil { + _ = d.Set("spot_instance_type", config.InstanceMarketOptions.SpotOptions.SpotInstanceType) + _ = d.Set("spot_max_price", config.InstanceMarketOptions.SpotOptions.MaxPrice) + } + + if config.InstanceChargePrepaid != nil { + _ = d.Set("instance_charge_type_prepaid_renew_flag", config.InstanceChargePrepaid.RenewFlag) + } return nil }) if err != nil { @@ -603,7 +684,32 @@ func resourceTencentCloudAsScalingConfigUpdate(d *schema.ResourceData, meta inte request.UserData = helper.String(v.(string)) } - chargeType := INSTANCE_CHARGE_TYPE_POSTPAID + chargeType, ok := d.Get("instance_charge_type").(string) + if !ok || chargeType == "" { + chargeType = INSTANCE_CHARGE_TYPE_POSTPAID + } + + if chargeType == INSTANCE_CHARGE_TYPE_SPOTPAID { + spotMaxPrice := d.Get("spot_max_price").(string) + spotInstanceType := d.Get("spot_instance_type").(string) + request.InstanceMarketOptions = &as.InstanceMarketOptionsRequest{ + MarketType: helper.String("spot"), + SpotOptions: &as.SpotMarketOptions{ + MaxPrice: &spotMaxPrice, + SpotInstanceType: &spotInstanceType, + }, + } + } + + if chargeType == INSTANCE_CHARGE_TYPE_PREPAID { + period := d.Get("instance_charge_type_prepaid_period").(int) + renewFlag := d.Get("instance_charge_type_prepaid_renew_flag").(string) + request.InstanceChargePrepaid = &as.InstanceChargePrepaid{ + Period: helper.IntInt64(period), + RenewFlag: &renewFlag, + } + } + request.InstanceChargeType = &chargeType if v, ok := d.GetOk("instance_types_check_policy"); ok { diff --git a/tencentcloud/resource_tc_as_scaling_config_test.go b/tencentcloud/resource_tc_as_scaling_config_test.go index 47688fb694..0b86cc78ea 100644 --- a/tencentcloud/resource_tc_as_scaling_config_test.go +++ b/tencentcloud/resource_tc_as_scaling_config_test.go @@ -92,6 +92,42 @@ func TestAccTencentCloudAsScalingConfig_full(t *testing.T) { }) } +func TestAccTencentCloudAsScalingConfig_charge(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCommon(t, ACCOUNT_TYPE_PREPAY) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAsScalingConfigDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAsScalingConfig_charge(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAsScalingConfigExists("tencentcloud_as_scaling_config.launch_configuration"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_config.launch_configuration", "instance_charge_type", "POSTPAID_BY_HOUR"), + ), + }, + { + Config: testAccAsScalingConfig_charge_spot(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAsScalingConfigExists("tencentcloud_as_scaling_config.launch_configuration"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_config.launch_configuration", "instance_charge_type", "SPOTPAID"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_config.launch_configuration", "spot_instance_type", "one-time"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_config.launch_configuration", "spot_max_price", "1000"), + ), + }, + { + Config: testAccAsScalingConfig_charge_perpaid(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAsScalingConfigExists("tencentcloud_as_scaling_config.launch_configuration"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_config.launch_configuration", "instance_charge_type", "PREPAID"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_config.launch_configuration", "instance_charge_type_prepaid_period", "1"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_config.launch_configuration", "instance_charge_type_prepaid_renew_flag", "NOTIFY_AND_MANUAL_RENEW"), + ), + }, + }, + }) +} + func testAccCheckAsScalingConfigExists(n string) resource.TestCheckFunc { return func(s *terraform.State) error { logId := getLogId(contextNil) @@ -211,3 +247,40 @@ resource "tencentcloud_as_scaling_config" "launch_configuration" { } ` } + +func testAccAsScalingConfig_charge() string { + return ` +resource "tencentcloud_as_scaling_config" "launch_configuration" { + configuration_name = "tf-as-basic" + image_id = "img-2lr9q49h" + instance_types = ["SA1.SMALL1"] + instance_charge_type = "POSTPAID_BY_HOUR" +} + ` +} + +func testAccAsScalingConfig_charge_spot() string { + return ` +resource "tencentcloud_as_scaling_config" "launch_configuration" { + configuration_name = "tf-as-basic" + image_id = "img-2lr9q49h" + instance_types = ["SA1.SMALL1"] + instance_charge_type = "SPOTPAID" + spot_instance_type = "one-time" + spot_max_price = "1000" +} + ` +} + +func testAccAsScalingConfig_charge_perpaid() string { + return ` +resource "tencentcloud_as_scaling_config" "launch_configuration" { + configuration_name = "tf-as-basic" + image_id = "img-2lr9q49h" + instance_types = ["SA1.SMALL1"] + instance_charge_type = "PREPAID" + instance_charge_type_prepaid_period = 1 + instance_charge_type_prepaid_renew_flag = "NOTIFY_AND_MANUAL_RENEW" +} + ` +} diff --git a/website/docs/r/as_scaling_config.html.markdown b/website/docs/r/as_scaling_config.html.markdown index cff65793a7..6016b173e5 100644 --- a/website/docs/r/as_scaling_config.html.markdown +++ b/website/docs/r/as_scaling_config.html.markdown @@ -41,6 +41,19 @@ resource "tencentcloud_as_scaling_config" "launch_configuration" { } ``` +Using SPOT charge type + +```hcl +resource "tencentcloud_as_scaling_config" "launch_configuration" { + configuration_name = "launch-configuration" + image_id = "img-9qabwvbn" + instance_types = ["SA1.SMALL1"] + instance_charge_type = "SPOTPAID" + spot_instance_type = "one-time" + spot_max_price = "1000" +} +``` + ## Argument Reference The following arguments are supported: @@ -53,6 +66,9 @@ The following arguments are supported: * `disk_type_policy` - (Optional) Policy of cloud disk type. Valid values: `ORIGINAL` and `AUTOMATIC`. Default is `ORIGINAL`. * `enhanced_monitor_service` - (Optional) To specify whether to enable cloud monitor service. Default is `TRUE`. * `enhanced_security_service` - (Optional) To specify whether to enable cloud security service. Default is `TRUE`. +* `instance_charge_type_prepaid_period` - (Optional) The tenancy (in month) of the prepaid instance, NOTE: it only works when instance_charge_type is set to `PREPAID`. Valid values are `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `24`, `36`. +* `instance_charge_type_prepaid_renew_flag` - (Optional) Auto renewal flag. Valid values: `NOTIFY_AND_AUTO_RENEW`: notify upon expiration and renew automatically, `NOTIFY_AND_MANUAL_RENEW`: notify upon expiration but do not renew automatically, `DISABLE_NOTIFY_AND_MANUAL_RENEW`: neither notify upon expiration nor renew automatically. Default value: `NOTIFY_AND_MANUAL_RENEW`. If this parameter is specified as `NOTIFY_AND_AUTO_RENEW`, the instance will be automatically renewed on a monthly basis if the account balance is sufficient. NOTE: it only works when instance_charge_type is set to `PREPAID`. +* `instance_charge_type` - (Optional) Charge type of instance. Valid values are `PREPAID`, `POSTPAID_BY_HOUR`, `SPOTPAID`. The default is `POSTPAID_BY_HOUR`. NOTE: `SPOTPAID` instance must set `spot_instance_type` and `spot_max_price` at the same time. * `instance_name_settings` - (Optional) Settings of CVM instance names. * `instance_tags` - (Optional) A list of tags used to associate different resources. * `internet_charge_type` - (Optional) Charge types for network traffic. Valid values: `BANDWIDTH_PREPAID`, `TRAFFIC_POSTPAID_BY_HOUR`, `TRAFFIC_POSTPAID_BY_HOUR` and `BANDWIDTH_PACKAGE`. @@ -63,6 +79,8 @@ The following arguments are supported: * `project_id` - (Optional) Specifys to which project the configuration belongs. * `public_ip_assigned` - (Optional) Specify whether to assign an Internet IP address. * `security_group_ids` - (Optional) Security groups to which a CVM instance belongs. +* `spot_instance_type` - (Optional) Type of spot instance, only support `one-time` now. Note: it only works when instance_charge_type is set to `SPOTPAID`. +* `spot_max_price` - (Optional) Max price of a spot instance, is the format of decimal string, for example "0.50". Note: it only works when instance_charge_type is set to `SPOTPAID`. * `system_disk_size` - (Optional) Volume of system disk in GB. Default is `50`. * `system_disk_type` - (Optional) Type of a CVM disk. Valid values: `CLOUD_PREMIUM` and `CLOUD_SSD`. Default is `CLOUD_PREMIUM`. valid when disk_type_policy is ORIGINAL. * `user_data` - (Optional) ase64-encoded User Data text, the length limit is 16KB.