Skip to content

Commit 3b2ce9f

Browse files
authored
feat: cvm - support multiple key_ids, deprecate key_name (#1285)
* feat: cvm - support multiple key_ids, deprecate key_name * fix: cvm - make keyids computed
1 parent cd4f29d commit 3b2ce9f

File tree

5 files changed

+95
-34
lines changed

5 files changed

+95
-34
lines changed

tencentcloud/resource_tc_instance.go

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ data "tencentcloud_cdh_instances" "list" {
8888
}
8989
9090
resource "tencentcloud_key_pair" "random_key" {
91-
key_name = "tf_example_key6"
91+
key_ids = ["tf_example_key6"]
9292
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDjd8fTnp7Dcuj4mLaQxf9Zs/ORgUL9fQxRCNKkPgP1paTy1I513maMX126i36Lxxl3+FUB52oVbo/FgwlIfX8hyCnv8MCxqnuSDozf1CD0/wRYHcTWAtgHQHBPCC2nJtod6cVC3kB18KeV4U7zsxmwFeBIxojMOOmcOBuh7+trRw=="
9393
}
9494
@@ -101,7 +101,7 @@ resource "tencentcloud_instance" "foo" {
101101
availability_zone = var.availability_zone
102102
instance_name = "terraform-testing"
103103
image_id = "img-ix05e4px"
104-
key_name = tencentcloud_key_pair.random_key.id
104+
key_ids = [tencentcloud_key_pair.random_key.id]
105105
placement_group_id = tencentcloud_placement_group.foo.id
106106
security_groups = ["sg-9c3f33xk"]
107107
system_disk_type = "CLOUD_PREMIUM"
@@ -424,10 +424,21 @@ func resourceTencentCloudInstance() *schema.Resource {
424424
},
425425
// login
426426
"key_name": {
427-
Type: schema.TypeString,
428-
Optional: true,
429-
Computed: true,
430-
Description: "The key pair to use for the instance, it looks like `skey-16jig7tx`. Modifying will cause the instance reset.",
427+
Type: schema.TypeString,
428+
Optional: true,
429+
Computed: true,
430+
Deprecated: "Please use `key_ids` instead.",
431+
ConflictsWith: []string{"key_ids"},
432+
Description: "The key pair to use for the instance, it looks like `skey-16jig7tx`. Modifying will cause the instance reset.",
433+
},
434+
"key_ids": {
435+
Type: schema.TypeSet,
436+
Optional: true,
437+
Computed: true,
438+
ConflictsWith: []string{"key_name", "password"},
439+
Description: "The key pair to use for the instance, it looks like `skey-16jig7tx`. Modifying will cause the instance reset.",
440+
Set: schema.HashString,
441+
Elem: &schema.Schema{Type: schema.TypeString},
431442
},
432443
"password": {
433444
Type: schema.TypeString,
@@ -446,7 +457,7 @@ func resourceTencentCloudInstance() *schema.Resource {
446457
return old == new
447458
}
448459
},
449-
ConflictsWith: []string{"key_name", "password"},
460+
ConflictsWith: []string{"key_name", "key_ids", "password"},
450461
Description: "Whether to keep image login or not, default is `false`. When the image type is private or shared or imported, this parameter can be set `true`. Modifying will cause the instance reset.",
451462
},
452463
"user_data": {
@@ -687,7 +698,10 @@ func resourceTencentCloudInstanceCreate(d *schema.ResourceData, meta interface{}
687698

688699
// login
689700
request.LoginSettings = &cvm.LoginSettings{}
690-
if v, ok := d.GetOk("key_name"); ok {
701+
keyIds := d.Get("key_ids").(*schema.Set).List()
702+
if len(keyIds) > 0 {
703+
request.LoginSettings.KeyIds = helper.InterfacesStringsPoint(keyIds)
704+
} else if v, ok := d.GetOk("key_name"); ok {
691705
request.LoginSettings.KeyIds = []*string{helper.String(v.(string))}
692706
}
693707
if v, ok := d.GetOk("password"); ok {
@@ -753,7 +767,6 @@ func resourceTencentCloudInstanceCreate(d *schema.ResourceData, meta interface{}
753767
}
754768
d.SetId(instanceId)
755769

756-
// wait for status
757770
//get system disk ID and data disk ID
758771
var systemDiskId string
759772
var dataDiskIds []string
@@ -904,7 +917,7 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
904917
return err
905918
}
906919

907-
if d.Get("image_id").(string) == "" || !IsContains(cvmImages, *instance.ImageId) {
920+
if d.Get("image_id").(string) == "" || instance.ImageId == nil || !IsContains(cvmImages, *instance.ImageId) {
908921
_ = d.Set("image_id", instance.ImageId)
909922
}
910923

@@ -1005,7 +1018,11 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
10051018
_ = d.Set("public_ip", instance.PublicIpAddresses[0])
10061019
}
10071020
if len(instance.LoginSettings.KeyIds) > 0 {
1008-
_ = d.Set("key_name", instance.LoginSettings.KeyIds[0])
1021+
if _, ok := d.GetOk("key_name"); ok {
1022+
_ = d.Set("key_name", instance.LoginSettings.KeyIds[0])
1023+
} else {
1024+
_ = d.Set("key_ids", instance.LoginSettings.KeyIds)
1025+
}
10091026
} else {
10101027
_ = d.Set("key_name", "")
10111028
}
@@ -1200,7 +1217,10 @@ func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{}
12001217
request.LoginSettings.Password = helper.String(v.(string))
12011218
}
12021219

1203-
if v, ok := d.GetOk("key_name"); ok {
1220+
if v, ok := d.GetOk("key_ids"); ok {
1221+
updateAttr = append(updateAttr, "key_ids")
1222+
request.LoginSettings.KeyIds = helper.InterfacesStringsPoint(v.(*schema.Set).List())
1223+
} else if v, ok := d.GetOk("key_name"); ok {
12041224
updateAttr = append(updateAttr, "key_name")
12051225
request.LoginSettings.KeyIds = []*string{helper.String(v.(string))}
12061226
}
@@ -1237,11 +1257,12 @@ func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{}
12371257
}
12381258

12391259
if d.HasChange("key_name") {
1240-
old, new := d.GetChange("key_name")
1241-
oldKeyId := old.(string)
1242-
keyId := new.(string)
1260+
o, n := d.GetChange("key_name")
1261+
oldKeyId := o.(string)
1262+
keyId := n.(string)
1263+
12431264
if oldKeyId != "" {
1244-
err := cvmService.UnbindKeyPair(ctx, oldKeyId, []*string{&instanceId})
1265+
err := cvmService.UnbindKeyPair(ctx, []*string{&oldKeyId}, []*string{&instanceId})
12451266
if err != nil {
12461267
return err
12471268
}
@@ -1252,7 +1273,39 @@ func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{}
12521273
}
12531274

12541275
if keyId != "" {
1255-
err = cvmService.BindKeyPair(ctx, keyId, instanceId)
1276+
err = cvmService.BindKeyPair(ctx, []*string{&keyId}, instanceId)
1277+
if err != nil {
1278+
return err
1279+
}
1280+
err = waitForOperationFinished(d, meta, 2*readRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false)
1281+
if err != nil {
1282+
return err
1283+
}
1284+
}
1285+
}
1286+
1287+
// support remove old `key_name` to `key_ids`, so do not follow "else"
1288+
if d.HasChange("key_ids") {
1289+
o, n := d.GetChange("key_ids")
1290+
ov := o.(*schema.Set)
1291+
1292+
nv := n.(*schema.Set)
1293+
1294+
adds := nv.Difference(ov)
1295+
removes := ov.Difference(nv)
1296+
1297+
if removes.Len() > 0 {
1298+
err := cvmService.UnbindKeyPair(ctx, helper.InterfacesStringsPoint(removes.List()), []*string{&instanceId})
1299+
if err != nil {
1300+
return err
1301+
}
1302+
err = waitForOperationFinished(d, meta, 2*readRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false)
1303+
if err != nil {
1304+
return err
1305+
}
1306+
}
1307+
if adds.Len() > 0 {
1308+
err = cvmService.BindKeyPair(ctx, helper.InterfacesStringsPoint(adds.List()), instanceId)
12561309
if err != nil {
12571310
return err
12581311
}
@@ -1261,7 +1314,6 @@ func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{}
12611314
return err
12621315
}
12631316
}
1264-
d.SetPartial("key_name")
12651317
}
12661318
}
12671319

tencentcloud/resource_tc_instance_test.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ func TestAccTencentCloudInstanceWithPrivateIP(t *testing.T) {
206206
})
207207
}
208208

209-
func TestAccTencentCloudInstanceWithKeyPair(t *testing.T) {
209+
func TestAccTencentCloudInstanceWithKeyPairs(t *testing.T) {
210210
id := "tencentcloud_instance.foo"
211211
resource.Test(t, resource.TestCase{
212212
PreCheck: func() { testAccPreCheck(t) },
@@ -216,25 +216,27 @@ func TestAccTencentCloudInstanceWithKeyPair(t *testing.T) {
216216
Steps: []resource.TestStep{
217217
{
218218
PreConfig: func() { testAccStepPreConfigSetTempAKSK(t, ACCOUNT_TYPE_COMMON) },
219-
Config: testAccTencentCloudInstanceWithKeyPair("key_pair_0"),
219+
Config: testAccTencentCloudInstanceWithKeyPair(
220+
"[tencentcloud_key_pair.key_pair_0.id, tencentcloud_key_pair.key_pair_1.id]",
221+
),
220222
Check: resource.ComposeTestCheckFunc(
221223
testAccCheckTencentCloudDataSourceID(id),
222224
testAccCheckTencentCloudInstanceExists(id),
223225
resource.TestCheckResourceAttr(id, "instance_status", "RUNNING"),
224-
resource.TestCheckResourceAttrSet(id, "key_name"),
226+
resource.TestCheckResourceAttr(id, "key_ids.#", "2"),
225227
),
226228
},
227229
{
228230
PreConfig: func() {
229231
testAccStepPreConfigSetTempAKSK(t, ACCOUNT_TYPE_COMMON)
230232
time.Sleep(time.Duration(time.Second * 5))
231233
},
232-
Config: testAccTencentCloudInstanceWithKeyPair("key_pair_1"),
234+
Config: testAccTencentCloudInstanceWithKeyPair("[tencentcloud_key_pair.key_pair_2.id]"),
233235
Check: resource.ComposeTestCheckFunc(
234236
testAccCheckTencentCloudDataSourceID(id),
235237
testAccCheckTencentCloudInstanceExists(id),
236238
resource.TestCheckResourceAttr(id, "instance_status", "RUNNING"),
237-
resource.TestCheckResourceAttrSet(id, "key_name"),
239+
resource.TestCheckResourceAttr(id, "key_ids.#", "1"),
238240
),
239241
},
240242
},
@@ -811,7 +813,8 @@ resource "tencentcloud_instance" "foo" {
811813
}
812814
`
813815

814-
func testAccTencentCloudInstanceWithKeyPair(keyName string) string {
816+
func testAccTencentCloudInstanceWithKeyPair(keyIds string) string {
817+
815818
return fmt.Sprintf(
816819
defaultInstanceVariable+`
817820
resource "tencentcloud_key_pair" "key_pair_0" {
@@ -824,16 +827,21 @@ resource "tencentcloud_key_pair" "key_pair_1" {
824827
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzwYE6KI8uULEvSNA2k1tlsLtMDe+x1Saw6yL3V1mk9NFws0K2BshYqsnP/BlYiGZv/Nld5xmGoA9LupOcUpyyGGSHZdBrMx1Dz9ajewe7kGowRWwwMAHTlzh9+iqeg/v6P5vW6EwK4hpGWgv06vGs3a8CzfbHu1YRbZAO/ysp3ymdL+vGvw/vzC0T+YwPMisn9wFD5FTlJ+Em6s9PzxqR/41t4YssmCwUV78ZoYL8CyB0emuB8wALvcXbdUVxMxpBEHd5U6ZP5+HPxU2WFbWqiFCuErLIZRuxFw8L/Ot+JOyNnadN1XU4crYDX5cML1i/ExXKVIDoBaLtgAJOpyeP"
825828
}
826829
830+
resource "tencentcloud_key_pair" "key_pair_2" {
831+
key_name = "key_pair_2"
832+
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDJ1zyoM55pKxJptZBKceZSEypPN7BOunqBR1Qj3Tz5uImJ+dwfKzggu8PGcbHtuN8D2n1BH/GDkiGFaz/sIYUJWWZudcdut+ra32MqUvk953Sztf12rsFC1+lZ1CYEgon8Lt6ehxn+61tsS31yfUmpL1mq2vuca7J0NLdPMpxIYkGlifyAMISMmxi/m7gPYpbdZTmhQQS2aOhuLm+B4MwtTvT58jqNzIaFU0h5sqAvGQfzI5pcxwYvFTeQeXjJZfaYapDHN0MAg0b/vIWWNrDLv7dlv//OKBIaL0LIzIGQS8XXhF3HlyqfDuf3bjLBIKzYGSV/DRqlEsGBgzinJZXvJZug5oq1n2njDFsdXEvL6fYsP4WLvBLiQlceQ7oXi7m5nfrwFTaX+mpo7dUOR9AcyQ1AAgCcM67orB4E33ycaArGHtpjnCnWUjqQ+yCj4EXsD4yOL77wGsmhkbboVNnYAD9MJWsFP03hZE7p/RHY0C5NfLPT3mL45oZxBpC5mis="
833+
}
834+
827835
resource "tencentcloud_instance" "foo" {
828836
instance_name = var.instance_name
829837
availability_zone = var.availability_cvm_zone
830838
image_id = data.tencentcloud_images.default.images.0.image_id
831839
instance_type = data.tencentcloud_instance_types.default.instance_types.0.instance_type
832-
key_name = tencentcloud_key_pair.%s.id
840+
key_ids = %s
833841
system_disk_type = "CLOUD_PREMIUM"
834842
}
835843
`,
836-
keyName,
844+
keyIds,
837845
)
838846
}
839847

tencentcloud/resource_tc_key_pair.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ func resourceTencentCloudKeyPairDelete(d *schema.ResourceData, meta interface{})
246246

247247
if len(keyPair.AssociatedInstanceIds) > 0 {
248248
err = resource.Retry(writeRetryTimeout, func() *resource.RetryError {
249-
errRet := cvmService.UnbindKeyPair(ctx, keyId, keyPair.AssociatedInstanceIds)
249+
errRet := cvmService.UnbindKeyPair(ctx, []*string{&keyId}, keyPair.AssociatedInstanceIds)
250250
if errRet != nil {
251251
if sdkErr, ok := errRet.(*errors.TencentCloudSDKError); ok {
252252
if sdkErr.Code == CVM_NOT_FOUND_ERROR {

tencentcloud/service_tencentcloud_cvm.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -694,10 +694,10 @@ func (me *CvmService) DeleteKeyPair(ctx context.Context, keyId string) error {
694694
return nil
695695
}
696696

697-
func (me *CvmService) UnbindKeyPair(ctx context.Context, keyId string, instanceIds []*string) error {
697+
func (me *CvmService) UnbindKeyPair(ctx context.Context, keyIds []*string, instanceIds []*string) error {
698698
logId := getLogId(ctx)
699699
request := cvm.NewDisassociateInstancesKeyPairsRequest()
700-
request.KeyIds = []*string{&keyId}
700+
request.KeyIds = keyIds
701701
request.InstanceIds = instanceIds
702702
request.ForceStop = helper.Bool(true)
703703

@@ -714,10 +714,10 @@ func (me *CvmService) UnbindKeyPair(ctx context.Context, keyId string, instanceI
714714
return nil
715715
}
716716

717-
func (me *CvmService) BindKeyPair(ctx context.Context, keyId, instanceId string) error {
717+
func (me *CvmService) BindKeyPair(ctx context.Context, keyIds []*string, instanceId string) error {
718718
logId := getLogId(ctx)
719719
request := cvm.NewAssociateInstancesKeyPairsRequest()
720-
request.KeyIds = []*string{&keyId}
720+
request.KeyIds = keyIds
721721
request.InstanceIds = []*string{&instanceId}
722722
request.ForceStop = helper.Bool(true)
723723

website/docs/r/instance.html.markdown

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ data "tencentcloud_cdh_instances" "list" {
9999
}
100100
101101
resource "tencentcloud_key_pair" "random_key" {
102-
key_name = "tf_example_key6"
102+
key_ids = ["tf_example_key6"]
103103
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDjd8fTnp7Dcuj4mLaQxf9Zs/ORgUL9fQxRCNKkPgP1paTy1I513maMX126i36Lxxl3+FUB52oVbo/FgwlIfX8hyCnv8MCxqnuSDozf1CD0/wRYHcTWAtgHQHBPCC2nJtod6cVC3kB18KeV4U7zsxmwFeBIxojMOOmcOBuh7+trRw=="
104104
}
105105
@@ -112,7 +112,7 @@ resource "tencentcloud_instance" "foo" {
112112
availability_zone = var.availability_zone
113113
instance_name = "terraform-testing"
114114
image_id = "img-ix05e4px"
115-
key_name = tencentcloud_key_pair.random_key.id
115+
key_ids = [tencentcloud_key_pair.random_key.id]
116116
placement_group_id = tencentcloud_placement_group.foo.id
117117
security_groups = ["sg-9c3f33xk"]
118118
system_disk_type = "CLOUD_PREMIUM"
@@ -160,7 +160,8 @@ The following arguments are supported:
160160
* `internet_charge_type` - (Optional, String) Internet charge type of the instance, Valid values are `BANDWIDTH_PREPAID`, `TRAFFIC_POSTPAID_BY_HOUR`, `BANDWIDTH_POSTPAID_BY_HOUR` and `BANDWIDTH_PACKAGE`. This value takes NO Effect when changing and does not need to be set when `allocate_public_ip` is false.
161161
* `internet_max_bandwidth_out` - (Optional, Int) Maximum outgoing bandwidth to the public network, measured in Mbps (Mega bits per second). This value does not need to be set when `allocate_public_ip` is false.
162162
* `keep_image_login` - (Optional, Bool) Whether to keep image login or not, default is `false`. When the image type is private or shared or imported, this parameter can be set `true`. Modifying will cause the instance reset.
163-
* `key_name` - (Optional, String) The key pair to use for the instance, it looks like `skey-16jig7tx`. Modifying will cause the instance reset.
163+
* `key_ids` - (Optional, Set: [`String`]) The key pair to use for the instance, it looks like `skey-16jig7tx`. Modifying will cause the instance reset.
164+
* `key_name` - (Optional, String, **Deprecated**) Please use `key_ids` instead. The key pair to use for the instance, it looks like `skey-16jig7tx`. Modifying will cause the instance reset.
164165
* `password` - (Optional, String) Password for the instance. In order for the new password to take effect, the instance will be restarted after the password change. Modifying will cause the instance reset.
165166
* `placement_group_id` - (Optional, String, ForceNew) The ID of a placement group.
166167
* `private_ip` - (Optional, String) The private IP to be assigned to this instance, must be in the provided subnet and available.

0 commit comments

Comments
 (0)