Skip to content

fix(cbs): [125536409] tencentcloud_cbs_snapshot_policy_attachment support storage_ids and import #3433

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

Merged
merged 2 commits into from
Jul 4, 2025
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/3433.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/tencentcloud_cbs_snapshot_policy_attachment: support `storage_ids` and `import`
```
199 changes: 158 additions & 41 deletions tencentcloud/services/cbs/resource_tc_cbs_snapshot_policy_attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,28 @@ func ResourceTencentCloudCbsSnapshotPolicyAttachment() *schema.Resource {
Create: resourceTencentCloudCbsSnapshotPolicyAttachmentCreate,
Read: resourceTencentCloudCbsSnapshotPolicyAttachmentRead,
Delete: resourceTencentCloudCbsSnapshotPolicyAttachmentDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"storage_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "ID of CBS.",
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ExactlyOneOf: []string{"storage_ids"},
Description: "ID of CBS.",
},

"storage_ids": {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
MinItems: 2,
ExactlyOneOf: []string{"storage_id"},
Description: "IDs of CBS.",
Elem: &schema.Schema{Type: schema.TypeString},
},

"snapshot_policy_id": {
Type: schema.TypeString,
Required: true,
Expand All @@ -38,96 +52,199 @@ func ResourceTencentCloudCbsSnapshotPolicyAttachment() *schema.Resource {

func resourceTencentCloudCbsSnapshotPolicyAttachmentCreate(d *schema.ResourceData, meta interface{}) error {
defer tccommon.LogElapsed("resource.tencentcloud_cbs_snapshot_policy_attachment.create")()
logId := tccommon.GetLogId(tccommon.ContextNil)
ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId)

storageId := d.Get("storage_id").(string)
policyId := d.Get("snapshot_policy_id").(string)
cbsService := CbsService{
client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(),
var (
logId = tccommon.GetLogId(tccommon.ContextNil)
ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId)
cbsService = CbsService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()}
storageId string
storageIds []string
policyId string
)

if v, ok := d.GetOk("storage_id"); ok {
storageId = v.(string)
}

if v, ok := d.GetOk("storage_ids"); ok {
for _, item := range v.(*schema.Set).List() {
if storageId, ok := item.(string); ok && storageId != "" {
storageIds = append(storageIds, storageId)
}
}
}

if v, ok := d.GetOk("snapshot_policy_id"); ok {
policyId = v.(string)
}

err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
errRet := cbsService.AttachSnapshotPolicy(ctx, storageId, policyId)
errRet := cbsService.AttachSnapshotPolicy(ctx, storageId, storageIds, policyId)
if errRet != nil {
return tccommon.RetryError(errRet)
}

return nil
})

if err != nil {
log.Printf("[CRITAL]%s cbs storage policy attach failed, reason:%s\n ", logId, err.Error())
return err
}

d.SetId(storageId + tccommon.FILED_SP + policyId)
if storageId != "" {
d.SetId(strings.Join([]string{storageId, policyId}, tccommon.FILED_SP))
} else {
storageIdsStr := strings.Join(storageIds, tccommon.COMMA_SP)
d.SetId(strings.Join([]string{storageIdsStr, policyId}, tccommon.FILED_SP))
}

return resourceTencentCloudCbsSnapshotPolicyAttachmentRead(d, meta)
}

func resourceTencentCloudCbsSnapshotPolicyAttachmentRead(d *schema.ResourceData, meta interface{}) error {
defer tccommon.LogElapsed("resource.tencentcloud_cbs_snapshot_policy_attachment.read")()
defer tccommon.InconsistentCheck(d, meta)()

logId := tccommon.GetLogId(tccommon.ContextNil)
ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId)
var (
logId = tccommon.GetLogId(tccommon.ContextNil)
ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId)
cbsService = CbsService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()}
id = d.Id()
storageId string
storageIds []string
)

id := d.Id()
idSplit := strings.Split(id, tccommon.FILED_SP)
if len(idSplit) != 2 {
return fmt.Errorf("tencentcloud_cbs_snapshot_policy_attachment id is illegal: %s", id)
}
storageId := idSplit[0]

storageIdObj := idSplit[0]
policyId := idSplit[1]
cbsService := CbsService{
client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(),

storageIdObjSplit := strings.Split(storageIdObj, tccommon.COMMA_SP)
if len(storageIdObjSplit) == 1 {
storageId = storageIdObjSplit[0]
} else {
storageIds = storageIdObjSplit
}
var policy *cbs.AutoSnapshotPolicy
var errRet error
err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError {
policy, errRet = cbsService.DescribeAttachedSnapshotPolicy(ctx, storageId, policyId)
if errRet != nil {
return tccommon.RetryError(errRet, tccommon.InternalError)

var (
policy *cbs.AutoSnapshotPolicy
errRet error
)

if storageId != "" {
err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError {
policy, errRet = cbsService.DescribeAttachedSnapshotPolicy(ctx, storageId, policyId)
if errRet != nil {
return tccommon.RetryError(errRet, tccommon.InternalError)
}

return nil
})

if err != nil {
log.Printf("[CRITAL]%s cbs storage policy attach failed, reason:%s\n ", logId, err.Error())
return err
}
return nil
})
if err != nil {
log.Printf("[CRITAL]%s cbs storage policy attach failed, reason:%s\n ", logId, err.Error())
return err

if policy == nil {
d.SetId("")
return nil
}

_ = d.Set("storage_id", storageId)
}
if policy == nil {
d.SetId("")
return nil

if len(storageIds) > 0 {
err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError {
policy, errRet = cbsService.DescribeAttachedSnapshotPolicyDisksById(ctx, policyId)
if errRet != nil {
return tccommon.RetryError(errRet, tccommon.InternalError)
}

return nil
})

if err != nil {
log.Printf("[CRITAL]%s cbs storage policy attach failed, reason:%s\n ", logId, err.Error())
return err
}

if policy == nil || policy.DiskIdSet == nil || len(policy.DiskIdSet) < 1 {
d.SetId("")
return nil
}

tmpList := GetDiskIds(storageIds, policy.DiskIdSet)
_ = d.Set("storage_ids", tmpList)
}
_ = d.Set("storage_id", storageId)

_ = d.Set("snapshot_policy_id", policyId)

return nil
}

func resourceTencentCloudCbsSnapshotPolicyAttachmentDelete(d *schema.ResourceData, meta interface{}) error {
defer tccommon.LogElapsed("resource.tencentcloud_cbs_snapshot_policy_attachment.delete")()
logId := tccommon.GetLogId(tccommon.ContextNil)
ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId)

id := d.Id()
var (
logId = tccommon.GetLogId(tccommon.ContextNil)
ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId)
cbsService = CbsService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()}
id = d.Id()
storageId string
storageIds []string
)

idSplit := strings.Split(id, tccommon.FILED_SP)
if len(idSplit) != 2 {
return fmt.Errorf("tencentcloud_cbs_snapshot_policy_attachment id is illegal: %s", id)
}
storageId := idSplit[0]

storageIdObj := idSplit[0]
policyId := idSplit[1]
cbsService := CbsService{
client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(),

storageIdObjSplit := strings.Split(storageIdObj, tccommon.COMMA_SP)
if len(storageIdObjSplit) == 1 {
storageId = storageIdObjSplit[0]
} else {
storageIds = storageIdObjSplit
}

err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
errRet := cbsService.UnattachSnapshotPolicy(ctx, storageId, policyId)
errRet := cbsService.UnattachSnapshotPolicy(ctx, storageId, storageIds, policyId)
if errRet != nil {
return tccommon.RetryError(errRet)
}

return nil
})

if err != nil {
log.Printf("[CRITAL]%s cbs storage policy unattach failed, reason:%s\n ", logId, err.Error())
return err
}

return nil
}

func GetDiskIds(A []string, B []*string) []string {
set := make(map[string]bool, len(B))
for _, ptr := range B {
if ptr != nil {
set[*ptr] = true
}
}

var tmpList []string
for _, s := range A {
if set[s] {
tmpList = append(tmpList, s)
}
}

return tmpList
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,95 @@
Provides a CBS snapshot policy attachment resource.

~> **NOTE:** To distinguish between `storage_id` and `storage_id`, use `storage_id` when there is only one diskId, otherwise use `storage_ids`.

Example Usage

Attachment CBS snapshot policy by storage_id

```hcl
resource "tencentcloud_cbs_snapshot_policy_attachment" "foo" {
storage_id = tencentcloud_cbs_storage.foo.id
snapshot_policy_id = tencentcloud_cbs_snapshot_policy.policy.id
resource "tencentcloud_cbs_storage" "example" {
storage_name = "tf-example"
storage_type = "CLOUD_SSD"
storage_size = 60
availability_zone = "ap-guangzhou-6"
project_id = 0
encrypt = false

tags = {
createBy = "Terraform"
}
}

resource "tencentcloud_cbs_snapshot_policy" "example" {
snapshot_policy_name = "tf-example"
repeat_weekdays = [1, 4]
repeat_hours = [1]
retention_days = 7
}

resource "tencentcloud_cbs_snapshot_policy_attachment" "example" {
storage_id = tencentcloud_cbs_storage.example.id
snapshot_policy_id = tencentcloud_cbs_snapshot_policy.example.id
}
```
```

Attachment CBS snapshot policy by storage_ids

```hcl
resource "tencentcloud_cbs_storage" "example1" {
storage_name = "tf-example1"
storage_type = "CLOUD_SSD"
storage_size = 60
availability_zone = "ap-guangzhou-6"
project_id = 0
encrypt = false

tags = {
createBy = "Terraform"
}
}

resource "tencentcloud_cbs_storage" "example2" {
storage_name = "tf-example2"
storage_type = "CLOUD_SSD"
storage_size = 60
availability_zone = "ap-guangzhou-6"
project_id = 0
encrypt = false

tags = {
createBy = "Terraform"
}
}

resource "tencentcloud_cbs_snapshot_policy" "example" {
snapshot_policy_name = "tf-example"
repeat_weekdays = [1, 4]
repeat_hours = [1]
retention_days = 7
}

resource "tencentcloud_cbs_snapshot_policy_attachment" "example" {
storage_ids = [
tencentcloud_cbs_storage.example1.id,
tencentcloud_cbs_storage.example2.id,
]
snapshot_policy_id = tencentcloud_cbs_snapshot_policy.example.id
}
```

Import

CBS snapshot policy attachment can be imported using the id, e.g.

If use storage_id

```
$ terraform import tencentcloud_cbs_snapshot_policy_attachment.example disk-fesgc43m#asp-8abupspr
```

If use storage_ids

```
$ terraform import tencentcloud_cbs_snapshot_policy_attachment.example disk-ghylus9y,disk-0tm61hla#asp-ng87uf4t
```
Loading
Loading