Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(clb): [121134331] tencentcloud_clb_instance support eip_address_id #3009

Merged
merged 3 commits into from
Dec 13, 2024
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
3 changes: 3 additions & 0 deletions .changelog/3009.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/tencentcloud_clb_instance: spport `eip_address_id`
```
140 changes: 140 additions & 0 deletions tencentcloud/services/clb/resource_tc_clb_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/pkg/errors"
clb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317"
vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"

"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
)
Expand Down Expand Up @@ -218,6 +219,11 @@ func ResourceTencentCloudClbInstance() *schema.Resource {
Optional: true,
Description: "If create dynamic vip CLB instance, `true` or `false`.",
},
"eip_address_id": {
Type: schema.TypeString,
Optional: true,
Description: "The unique ID of the EIP, such as eip-1v2rmbwk, is only applicable to the intranet load balancing binding EIP. During the EIP change, there may be a brief network interruption.",
},
"domain": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -406,6 +412,10 @@ func resourceTencentCloudClbInstanceCreate(d *schema.ResourceData, meta interfac
request.DynamicVip = helper.Bool(v.(bool))
}

if v, ok := d.GetOk("eip_address_id"); ok {
request.EipAddressId = helper.String(v.(string))
}

if tags := helper.GetTags(d, "tags"); len(tags) > 0 {
for k, v := range tags {
tmpKey := k
Expand Down Expand Up @@ -675,6 +685,40 @@ func resourceTencentCloudClbInstanceRead(d *schema.ResourceData, meta interface{
_ = d.Set("snat_pro", instance.SnatPro)
}

if *instance.LoadBalancerType == "INTERNAL" {
request := vpc.NewDescribeAddressesRequest()
request.Filters = []*vpc.Filter{
{
Name: helper.String("instance-id"),
Values: helper.Strings([]string{clbId}),
},
}
err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().DescribeAddresses(request)
if e != nil {
return tccommon.RetryError(e)
}

if result == nil || result.Response == nil || result.Response.AddressSet == nil {
e = fmt.Errorf("Describe CLB instance EIP failed")
return resource.NonRetryableError(e)
}

if len(result.Response.AddressSet) == 1 {
if result.Response.AddressSet[0].AddressId != nil {
_ = d.Set("eip_address_id", result.Response.AddressSet[0].AddressId)
}
}

return nil
})

if err != nil {
log.Printf("[CRITAL]%s Describe CLB instance EIP failed, reason:%+v", logId, err)
return err
}
}

tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn()
tagService := svctag.NewTagService(tcClient)
tags, err := tagService.DescribeResourceTags(ctx, "clb", "clb", tcClient.Region, d.Id())
Expand Down Expand Up @@ -932,6 +976,102 @@ func resourceTencentCloudClbInstanceUpdate(d *schema.ResourceData, meta interfac
}
}

if d.HasChange("eip_address_id") {
oldEip, newEip := d.GetChange("eip_address_id")
oldEipStr := oldEip.(string)
newEipStr := newEip.(string)
// delete old first
if oldEipStr != "" {
request := vpc.NewDisassociateAddressRequest()
request.AddressId = helper.String(oldEipStr)
err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
_, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().DisassociateAddress(request)
if e != nil {
return tccommon.RetryError(e)
}

return nil
})

if err != nil {
log.Printf("[CRITAL]%s Disassociate EIP failed, reason:%+v", logId, err)
return err
}

// wait
eipRequest := vpc.NewDescribeAddressesRequest()
eipRequest.AddressIds = helper.Strings([]string{oldEipStr})
err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().DescribeAddresses(eipRequest)
if e != nil {
return tccommon.RetryError(e)
}

if result == nil || result.Response == nil || result.Response.AddressSet == nil || len(result.Response.AddressSet) != 1 {
e = fmt.Errorf("Describe CLB instance EIP failed")
return resource.NonRetryableError(e)
}

if *result.Response.AddressSet[0].AddressStatus != "UNBIND" {
return resource.RetryableError(fmt.Errorf("EIP status is still %s", *result.Response.AddressSet[0].AddressStatus))
}

return nil
})

if err != nil {
log.Printf("[CRITAL]%s Describe CLB instance EIP failed, reason:%+v", logId, err)
return err
}
}

// attach new
if newEipStr != "" {
request := vpc.NewAssociateAddressRequest()
request.AddressId = helper.String(newEipStr)
request.InstanceId = helper.String(clbId)
err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
_, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().AssociateAddress(request)
if e != nil {
return tccommon.RetryError(e)
}

return nil
})

if err != nil {
log.Printf("[CRITAL]%s Associate EIP failed, reason:%+v", logId, err)
return err
}

// wait
eipRequest := vpc.NewDescribeAddressesRequest()
eipRequest.AddressIds = helper.Strings([]string{newEipStr})
err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().DescribeAddresses(eipRequest)
if e != nil {
return tccommon.RetryError(e)
}

if result == nil || result.Response == nil || result.Response.AddressSet == nil || len(result.Response.AddressSet) != 1 {
e = fmt.Errorf("Describe CLB instance EIP failed")
return resource.NonRetryableError(e)
}

if *result.Response.AddressSet[0].AddressStatus != "BIND" {
return resource.RetryableError(fmt.Errorf("EIP status is still %s", *result.Response.AddressSet[0].AddressStatus))
}

return nil
})

if err != nil {
log.Printf("[CRITAL]%s Describe CLB instance EIP failed, reason:%+v", logId, err)
return err
}
}
}

if d.HasChange("tags") {
oldValue, newValue := d.GetChange("tags")
replaceTags, deleteTags := svctag.DiffTags(oldValue.(map[string]interface{}), newValue.(map[string]interface{}))
Expand Down
37 changes: 37 additions & 0 deletions tencentcloud/services/clb/resource_tc_clb_instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,43 @@ resource "tencentcloud_clb_instance" "example" {
}
```

Create CLB with eip_address_id, Only support INTERNAL CLB

```hcl
variable "availability_zone" {
default = "ap-guangzhou-4"
}

// create vpc
resource "tencentcloud_vpc" "vpc" {
cidr_block = "10.0.0.0/16"
name = "vpc"
}

// create subnet
resource "tencentcloud_subnet" "subnet" {
vpc_id = tencentcloud_vpc.vpc.id
availability_zone = var.availability_zone
name = "subnet"
cidr_block = "10.0.1.0/24"
is_multicast = false
}

// create clb
resource "tencentcloud_clb_instance" "example" {
network_type = "INTERNAL"
clb_name = "tf-example"
project_id = 0
vpc_id = tencentcloud_vpc.vpc.id
subnet_id = tencentcloud_subnet.subnet.id
eip_address_id = "eip-lt0w6jhq"

tags = {
tagKey = "tagValue"
}
}
```

Create dedicated cluster clb

```hcl
Expand Down
38 changes: 38 additions & 0 deletions website/docs/r/clb_instance.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,43 @@ resource "tencentcloud_clb_instance" "example" {
}
```

### Create CLB with eip_address_id, Only support INTERNAL CLB

```hcl
variable "availability_zone" {
default = "ap-guangzhou-4"
}

// create vpc
resource "tencentcloud_vpc" "vpc" {
cidr_block = "10.0.0.0/16"
name = "vpc"
}

// create subnet
resource "tencentcloud_subnet" "subnet" {
vpc_id = tencentcloud_vpc.vpc.id
availability_zone = var.availability_zone
name = "subnet"
cidr_block = "10.0.1.0/24"
is_multicast = false
}

// create clb
resource "tencentcloud_clb_instance" "example" {
network_type = "INTERNAL"
clb_name = "tf-example"
project_id = 0
vpc_id = tencentcloud_vpc.vpc.id
subnet_id = tencentcloud_subnet.subnet.id
eip_address_id = "eip-lt0w6jhq"

tags = {
tagKey = "tagValue"
}
}
```

### Create dedicated cluster clb

```hcl
Expand Down Expand Up @@ -486,6 +523,7 @@ The following arguments are supported:
* `cluster_id` - (Optional, String, ForceNew) Cluster ID.
* `delete_protect` - (Optional, Bool) Whether to enable delete protection.
* `dynamic_vip` - (Optional, Bool) If create dynamic vip CLB instance, `true` or `false`.
* `eip_address_id` - (Optional, String) The unique ID of the EIP, such as eip-1v2rmbwk, is only applicable to the intranet load balancing binding EIP. During the EIP change, there may be a brief network interruption.
* `internet_bandwidth_max_out` - (Optional, Int) Max bandwidth out, only applicable to open CLB. Valid value ranges is [1, 2048]. Unit is MB.
* `internet_charge_type` - (Optional, String) Internet charge type, only applicable to open CLB. Valid values are `TRAFFIC_POSTPAID_BY_HOUR`, `BANDWIDTH_POSTPAID_BY_HOUR` and `BANDWIDTH_PACKAGE`.
* `load_balancer_pass_to_target` - (Optional, Bool) Whether the target allow flow come from clb. If value is true, only check security group of clb, or check both clb and backend instance security group.
Expand Down
Loading