Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions tencentcloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ Cloud Load Balancer(CLB)
tencentcloud_clb_log_set
tencentcloud_clb_log_topic
tencentcloud_clb_customized_config
tencentcloud_clb_snat_ip

Cloud Object Storage(COS)
Data Source
Expand Down Expand Up @@ -965,6 +966,7 @@ func Provider() terraform.ResourceProvider {
"tencentcloud_clb_log_set": resourceTencentCloudClbLogSet(),
"tencentcloud_clb_log_topic": resourceTencentCloudClbLogTopic(),
"tencentcloud_clb_customized_config": resourceTencentCloudClbCustomizedConfig(),
"tencentcloud_clb_snat_ip": resourceTencentCloudClbSnatIp(),
"tencentcloud_container_cluster": resourceTencentCloudContainerCluster(),
"tencentcloud_container_cluster_instance": resourceTencentCloudContainerClusterInstance(),
"tencentcloud_kubernetes_cluster": resourceTencentCloudTkeCluster(),
Expand Down
105 changes: 78 additions & 27 deletions tencentcloud/resource_tc_clb_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ import (
"log"
"sync"

"github.com/hashicorp/terraform-plugin-sdk/helper/hashcode"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/pkg/errors"
Expand Down Expand Up @@ -253,6 +255,30 @@ func resourceTencentCloudClbInstance() *schema.Resource {
Computed: true,
Description: "Vpc information of backend services are attached the CLB instance. Only supports `OPEN` CLBs.",
},
"snat_pro": {
Type: schema.TypeBool,
Optional: true,
Description: "Indicates whether Binding IPs of other VPCs feature switch.",
},
"snat_ips": {
Type: schema.TypeList,
Optional: true,
Description: "Snat Ip List, required with `snat_pro=true`. NOTE: This argument cannot be read and modified here because dynamic ip is untraceable, please import resource `tencentcloud_clb_snat_ip` to handle fixed ips.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ip": {
Type: schema.TypeString,
Optional: true,
Description: "Snat IP address, If set to empty will auto allocated.",
},
"subnet_id": {
Type: schema.TypeString,
Required: true,
Description: "Snat subnet ID.",
},
},
},
},
"tags": {
Type: schema.TypeMap,
Optional: true,
Expand Down Expand Up @@ -366,6 +392,24 @@ func resourceTencentCloudClbInstanceCreate(d *schema.ResourceData, meta interfac
request.AddressIPVersion = helper.String(v.(string))
}

if v, ok := d.GetOk("snat_pro"); ok {
request.SnatPro = helper.Bool(v.(bool))
}

if v, ok := d.Get("snat_ips").([]interface{}); ok && len(v) > 0 {
for i := range v {
item := v[i].(map[string]interface{})
subnetId := item["subnet_id"].(string)
snatIp := &clb.SnatIp{
SubnetId: &subnetId,
}
if v, ok := item["ip"].(string); ok && v != "" {
snatIp.Ip = &v
}
request.SnatIps = append(request.SnatIps, snatIp)
}
}

v, ok := d.GetOk("internet_charge_type")
bv, bok := d.GetOk("internet_bandwidth_max_out")
pv, pok := d.GetOk("bandwidth_package_id")
Expand Down Expand Up @@ -613,6 +657,10 @@ func resourceTencentCloudClbInstanceRead(d *schema.ResourceData, meta interface{
_ = d.Set("log_set_id", instance.LogSetId)
_ = d.Set("log_topic_id", instance.LogTopicId)

if _, ok := d.GetOk("snat_pro"); ok {
_ = d.Set("snat_pro", instance.SnatPro)
}

tcClient := meta.(*TencentCloudClient).apiV3Conn
tagService := &TagService{client: tcClient}
tags, err := tagService.DescribeResourceTags(ctx, "clb", "clb", tcClient.Region, d.Id())
Expand All @@ -631,15 +679,19 @@ func resourceTencentCloudClbInstanceUpdate(d *schema.ResourceData, meta interfac
defer clbActionMu.Unlock()

logId := getLogId(contextNil)
ctx := context.WithValue(context.TODO(), logIdKey, logId)

d.Partial(true)

clbId := d.Id()
request := clb.NewModifyLoadBalancerAttributesRequest()
request.LoadBalancerId = helper.String(clbId)
clbName := ""
targetRegionInfo := clb.TargetRegionInfo{}
internet := clb.InternetAccessible{}
changed := false
isLoadBalancerPassToTgt := false
snatPro := d.Get("snat_pro").(bool)

if d.HasChange("clb_name") {
changed = true
Expand All @@ -651,6 +703,7 @@ func resourceTencentCloudClbInstanceUpdate(d *schema.ResourceData, meta interfac
if flag {
return fmt.Errorf("[CHECK][CLB instance][Update] check: Same CLB name %s exists!", clbName)
}
request.LoadBalancerName = helper.String(clbName)
}

if d.HasChange("target_region_info_region") || d.HasChange("target_region_info_vpc_id") {
Expand All @@ -664,6 +717,7 @@ func resourceTencentCloudClbInstanceUpdate(d *schema.ResourceData, meta interfac
Region: &region,
VpcId: &vpcId,
}
request.TargetRegionInfo = &targetRegionInfo
}

if d.HasChange("internet_charge_type") || d.HasChange("internet_bandwidth_max_out") {
Expand All @@ -679,28 +733,25 @@ func resourceTencentCloudClbInstanceUpdate(d *schema.ResourceData, meta interfac
if bandwidth > 0 {
internet.InternetMaxBandwidthOut = helper.IntInt64(bandwidth)
}
request.InternetChargeInfo = &internet
}

if d.HasChange("load_balancer_pass_to_target") {
changed = true
isLoadBalancerPassToTgt = d.Get("load_balancer_pass_to_target").(bool)
request.LoadBalancerPassToTarget = &isLoadBalancerPassToTgt
}

if d.HasChange("snat_pro") {
changed = true
request.SnatPro = &snatPro
}

if d.HasChange("snat_ips") {
return fmt.Errorf("`snat_ips`")
}

if changed {
request := clb.NewModifyLoadBalancerAttributesRequest()
request.LoadBalancerId = helper.String(clbId)
if d.HasChange("clb_name") {
request.LoadBalancerName = helper.String(clbName)
}
if d.HasChange("target_region_info_region") || d.HasChange("target_region_info_vpc_id") {
request.TargetRegionInfo = &targetRegionInfo
}
if d.HasChange("internet_charge_type") || d.HasChange("internet_bandwidth_max_out") {
request.InternetChargeInfo = &internet
}
if d.HasChange("load_balancer_pass_to_target") {
request.LoadBalancerPassToTarget = &isLoadBalancerPassToTgt
}
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
response, e := meta.(*TencentCloudClient).apiV3Conn.UseClbClient().ModifyLoadBalancerAttributes(request)
if e != nil {
Expand All @@ -720,18 +771,6 @@ func resourceTencentCloudClbInstanceUpdate(d *schema.ResourceData, meta interfac
log.Printf("[CRITAL]%s update CLB instance failed, reason:%+v", logId, err)
return err
}
if d.HasChange("clb_name") {
d.SetPartial("clb_name")
}
if d.HasChange("clb_vips") {
d.SetPartial("clb_vips")
}
if d.HasChange("target_region_info_region") {
d.SetPartial("target_region_info_region")
}
if d.HasChange("target_region_info_vpc_id") {
d.SetPartial("target_region_info_vpc_id")
}
}

if d.HasChange("security_groups") {
Expand Down Expand Up @@ -794,7 +833,7 @@ func resourceTencentCloudClbInstanceUpdate(d *schema.ResourceData, meta interfac
return err
}
}
ctx := context.WithValue(context.TODO(), logIdKey, logId)

if d.HasChange("tags") {

oldValue, newValue := d.GetChange("tags")
Expand Down Expand Up @@ -875,3 +914,15 @@ func checkSameName(name string, meta interface{}) (flag bool, errRet error) {
errRet = err
return
}

func snatIpSetInitFn(i interface{}) int {
item := i.(map[string]interface{})
subnet := item["subnet_id"].(string)
allocatedIp := item["allocated_snat_ip"].(string)
ip, ok := item["ip"].(string)

if !ok || ip == "" {
ip = allocatedIp
}
return hashcode.String(subnet + ip)
}
51 changes: 51 additions & 0 deletions tencentcloud/resource_tc_clb_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
)

const BasicClbName = "tf-clb-basic"
const SnatClbName = "tf-clb-snat"
const InternalClbName = "tf-clb-internal"
const InternalClbNameUpdate = "tf-clb-update-internal"
const SingleClbName = "single-open-clb"
Expand Down Expand Up @@ -136,6 +137,27 @@ func TestAccTencentCloudClbInstance_open(t *testing.T) {
})
}

func TestAccTencentCloudClbInstance_snat(t *testing.T) {
t.Parallel()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckClbInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccClbInstance_snat,
Check: resource.ComposeTestCheckFunc(
testAccCheckClbInstanceExists("tencentcloud_clb_instance.clb_basic"),
resource.TestCheckResourceAttr("tencentcloud_clb_instance.clb_basic", "network_type", "OPEN"),
resource.TestCheckResourceAttr("tencentcloud_clb_instance.clb_basic", "clb_name", SnatClbName),
resource.TestCheckResourceAttr("tencentcloud_clb_instance.clb_basic", "snat_pro", "true"),
),
},
},
})
}

func TestAccTencentCloudClbInstance_internal(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -310,6 +332,35 @@ resource "tencentcloud_clb_instance" "clb_basic" {
}
`

const testAccClbInstance_snat = `
data "tencentcloud_vpc_instances" "gz3vpc" {
name = "Default-"
is_default = true
}

data "tencentcloud_vpc_subnets" "gz3" {
vpc_id = data.tencentcloud_vpc_instances.gz3vpc.instance_list.0.vpc_id
}

locals {
keep_clb_subnets = [for subnet in data.tencentcloud_vpc_subnets.gz3.instance_list: lookup(subnet, "subnet_id") if lookup(subnet, "name") == "keep-clb-sub"]
subnets = [for subnet in data.tencentcloud_vpc_subnets.gz3.instance_list: lookup(subnet, "subnet_id") ]
subnet_for_clb_snat = concat(local.keep_clb_subnets, local.subnets)
}

resource "tencentcloud_clb_instance" "clb_basic" {
network_type = "OPEN"
clb_name = "` + SnatClbName + `"
snat_pro = true
snat_ips {
subnet_id = local.subnet_for_clb_snat.0
}
snat_ips {
subnet_id = local.subnet_for_clb_snat.1
}
}
`

const testAccClbInstance_internal = `
variable "availability_zone" {
default = "ap-guangzhou-3"
Expand Down
Loading