Skip to content

Commit dd44199

Browse files
authored
add cvm ssh key (#1929)
* add cvm ssh key * add changelog
1 parent fc33b16 commit dd44199

File tree

13 files changed

+3284
-233
lines changed

13 files changed

+3284
-233
lines changed

.changelog/1929.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:new-resource
2+
tencentcloud_ssm_ssh_key_pair_secret
3+
```

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ require (
7171
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.486
7272
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sqlserver v1.0.689
7373
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.199
74-
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssm v1.0.199
74+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssm v1.0.691
7575
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sts v1.0.524
7676
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag v1.0.677
7777
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tat v1.0.634

go.sum

Lines changed: 9 additions & 30 deletions
Large diffs are not rendered by default.

tencentcloud/provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,7 @@ Secrets Manager(SSM)
863863
Resource
864864
tencentcloud_ssm_secret
865865
tencentcloud_ssm_secret_version
866+
tencentcloud_ssm_ssh_key_pair_secret
866867
867868
TcaplusDB
868869
Data Source
@@ -2623,6 +2624,7 @@ func Provider() *schema.Provider {
26232624
"tencentcloud_kms_key": resourceTencentCloudKmsKey(),
26242625
"tencentcloud_kms_external_key": resourceTencentCloudKmsExternalKey(),
26252626
"tencentcloud_ssm_secret": resourceTencentCloudSsmSecret(),
2627+
"tencentcloud_ssm_ssh_key_pair_secret": resourceTencentCloudSsmSshKeyPairSecret(),
26262628
"tencentcloud_ssm_secret_version": resourceTencentCloudSsmSecretVersion(),
26272629
"tencentcloud_cdh_instance": resourceTencentCloudCdhInstance(),
26282630
"tencentcloud_dnspod_domain_instance": resourceTencentCloudDnspodDomainInstance(),
Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
/*
2+
Provides a resource to create a ssm ssh key pair secret
3+
4+
Example Usage
5+
6+
```hcl
7+
data "tencentcloud_kms_keys" "kms" {
8+
key_state = 1
9+
}
10+
11+
resource "tencentcloud_ssm_ssh_key_pair_secret" "ssh_key_pair_secret" {
12+
secret_name = "tf-ssh-key-secret"
13+
project_id = 0
14+
description = "for tf test"
15+
kms_key_id = data.tencentcloud_kms_keys.kms.key_list.0.key_id
16+
ssh_key_name = "tf_ssh_test"
17+
status = "Disabled"
18+
tags = {
19+
"test" = "test"
20+
}
21+
clean_ssh_key = true
22+
}
23+
```
24+
25+
Import
26+
27+
ssm ssh_key_pair_secret can be imported using the id, e.g.
28+
29+
```
30+
terraform import tencentcloud_ssm_ssh_key_pair_secret.ssh_key_pair_secret ssh_key_pair_secret_name
31+
```
32+
*/
33+
package tencentcloud
34+
35+
import (
36+
"context"
37+
"fmt"
38+
"log"
39+
40+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
41+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
42+
ssm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssm/v20190923"
43+
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
44+
)
45+
46+
func resourceTencentCloudSsmSshKeyPairSecret() *schema.Resource {
47+
return &schema.Resource{
48+
Create: resourceTencentCloudSsmSshKeyPairSecretCreate,
49+
Read: resourceTencentCloudSsmSshKeyPairSecretRead,
50+
Update: resourceTencentCloudSsmSshKeyPairSecretUpdate,
51+
Delete: resourceTencentCloudSsmSshKeyPairSecretDelete,
52+
Importer: &schema.ResourceImporter{
53+
State: schema.ImportStatePassthrough,
54+
},
55+
Schema: map[string]*schema.Schema{
56+
"secret_name": {
57+
Required: true,
58+
Type: schema.TypeString,
59+
ForceNew: true,
60+
Description: "Secret name, which must be unique in the same region. It can contain 128 bytes of letters, digits, hyphens and underscores and must begin with a letter or digit.",
61+
},
62+
63+
"project_id": {
64+
Required: true,
65+
Type: schema.TypeInt,
66+
Description: "ID of the project to which the created SSH key belongs.",
67+
},
68+
69+
"description": {
70+
Optional: true,
71+
Type: schema.TypeString,
72+
Description: "Description, such as what it is used for. It contains up to 2,048 bytes.",
73+
},
74+
75+
"kms_key_id": {
76+
Optional: true,
77+
Type: schema.TypeString,
78+
Description: "Specifies a KMS CMK to encrypt the secret.If this parameter is left empty, the CMK created by Secrets Manager by default will be used for encryption.You can also specify a custom KMS CMK created in the same region for encryption.",
79+
},
80+
81+
"ssh_key_name": {
82+
Optional: true,
83+
Type: schema.TypeString,
84+
Description: "Name of the SSH key pair, which only contains digits, letters and underscores and must start with a digit or letter. The maximum length is 25 characters.",
85+
},
86+
87+
"status": {
88+
Optional: true,
89+
Type: schema.TypeString,
90+
Computed: true,
91+
ValidateFunc: validateAllowedStringValue([]string{"Enabled", "Disabled"}),
92+
Description: "Enable or Disable Secret. Valid values is `Enabled` or `Disabled`. Default is `Enabled`.",
93+
},
94+
95+
"clean_ssh_key": {
96+
Optional: true,
97+
Type: schema.TypeBool,
98+
Description: "Specifies whether to delete the SSH key from both the secret and the SSH key list in the CVM console. This field is only take effect when delete SSH key secrets. Valid values: " +
99+
"`True`: deletes SSH key from both the secret and SSH key list in the CVM console. Note that the deletion will fail if the SSH key is already bound to a CVM instance." +
100+
"`False`: only deletes the SSH key information in the secret.",
101+
},
102+
103+
"create_time": {
104+
Type: schema.TypeInt,
105+
Computed: true,
106+
Description: "Credential creation time in UNIX timestamp format.",
107+
},
108+
109+
"secret_type": {
110+
Type: schema.TypeInt,
111+
Computed: true,
112+
Description: "`0`: user-defined secret. `1`: Tencent Cloud services secret. `2`: SSH key secret. `3`: Tencent Cloud API key secret. Note: this field may return `null`, indicating that no valid values can be obtained.",
113+
},
114+
},
115+
}
116+
}
117+
118+
func resourceTencentCloudSsmSshKeyPairSecretCreate(d *schema.ResourceData, meta interface{}) error {
119+
defer logElapsed("resource.tencentcloud_ssm_ssh_key_pair_secret.create")()
120+
defer inconsistentCheck(d, meta)()
121+
122+
logId := getLogId(contextNil)
123+
124+
var (
125+
request = ssm.NewCreateSSHKeyPairSecretRequest()
126+
response = ssm.NewCreateSSHKeyPairSecretResponse()
127+
secretName string
128+
)
129+
if v, ok := d.GetOk("secret_name"); ok {
130+
request.SecretName = helper.String(v.(string))
131+
}
132+
133+
if v, ok := d.GetOkExists("project_id"); ok {
134+
request.ProjectId = helper.IntInt64(v.(int))
135+
}
136+
137+
if v, ok := d.GetOk("description"); ok {
138+
request.Description = helper.String(v.(string))
139+
}
140+
141+
if v, ok := d.GetOk("kms_key_id"); ok {
142+
request.KmsKeyId = helper.String(v.(string))
143+
}
144+
145+
if v, ok := d.GetOk("ssh_key_name"); ok {
146+
request.SSHKeyName = helper.String(v.(string))
147+
}
148+
149+
// Not support yet, because of can not query tags
150+
if v := helper.GetTags(d, "tags"); len(v) > 0 {
151+
for tagKey, tagValue := range v {
152+
tag := ssm.Tag{
153+
TagKey: helper.String(tagKey),
154+
TagValue: helper.String(tagValue),
155+
}
156+
request.Tags = append(request.Tags, &tag)
157+
}
158+
}
159+
160+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
161+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseSsmClient().CreateSSHKeyPairSecret(request)
162+
if e != nil {
163+
return retryError(e)
164+
} else {
165+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
166+
}
167+
response = result
168+
return nil
169+
})
170+
if err != nil {
171+
log.Printf("[CRITAL]%s create ssm sshKeyPairSecret failed, reason:%+v", logId, err)
172+
return err
173+
}
174+
175+
secretName = *response.Response.SecretName
176+
d.SetId(secretName)
177+
178+
// update status if disabled
179+
if v, ok := d.GetOk("status"); ok {
180+
status := v.(string)
181+
if status == "Disabled" {
182+
logId := getLogId(contextNil)
183+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
184+
service := SsmService{client: meta.(*TencentCloudClient).apiV3Conn}
185+
err := service.DisableSecret(ctx, secretName)
186+
if err != nil {
187+
return err
188+
}
189+
}
190+
}
191+
192+
return resourceTencentCloudSsmSshKeyPairSecretRead(d, meta)
193+
}
194+
195+
func resourceTencentCloudSsmSshKeyPairSecretRead(d *schema.ResourceData, meta interface{}) error {
196+
defer logElapsed("resource.tencentcloud_ssm_ssh_key_pair_secret.read")()
197+
defer inconsistentCheck(d, meta)()
198+
199+
logId := getLogId(contextNil)
200+
201+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
202+
203+
service := SsmService{client: meta.(*TencentCloudClient).apiV3Conn}
204+
205+
secretName := d.Id()
206+
207+
sshKeyPairSecret, err := service.DescribeSecretById(ctx, secretName, 2)
208+
if err != nil {
209+
return err
210+
}
211+
212+
if sshKeyPairSecret == nil {
213+
d.SetId("")
214+
log.Printf("[WARN]%s resource `SsmSshKeyPairSecret` [%s] not found, please check if it has been deleted.\n", logId, d.Id())
215+
return nil
216+
}
217+
218+
if sshKeyPairSecret.SecretName != nil {
219+
_ = d.Set("secret_name", sshKeyPairSecret.SecretName)
220+
}
221+
222+
if sshKeyPairSecret.ProjectID != nil {
223+
_ = d.Set("project_id", sshKeyPairSecret.ProjectID)
224+
}
225+
226+
if sshKeyPairSecret.Description != nil {
227+
_ = d.Set("description", sshKeyPairSecret.Description)
228+
}
229+
230+
if sshKeyPairSecret.KmsKeyId != nil {
231+
_ = d.Set("kms_key_id", sshKeyPairSecret.KmsKeyId)
232+
}
233+
234+
if sshKeyPairSecret.ResourceName != nil {
235+
_ = d.Set("ssh_key_name", sshKeyPairSecret.ResourceName)
236+
}
237+
238+
if sshKeyPairSecret.Status != nil {
239+
_ = d.Set("status", sshKeyPairSecret.Status)
240+
}
241+
242+
if sshKeyPairSecret.CreateTime != nil {
243+
_ = d.Set("create_time", sshKeyPairSecret.CreateTime)
244+
}
245+
246+
if sshKeyPairSecret.SecretType != nil {
247+
_ = d.Set("secret_type", sshKeyPairSecret.SecretType)
248+
}
249+
250+
return nil
251+
}
252+
253+
func resourceTencentCloudSsmSshKeyPairSecretUpdate(d *schema.ResourceData, meta interface{}) error {
254+
defer logElapsed("resource.tencentcloud_ssm_ssh_key_pair_secret.update")()
255+
defer inconsistentCheck(d, meta)()
256+
257+
logId := getLogId(contextNil)
258+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
259+
260+
secretName := d.Id()
261+
262+
immutableArgs := []string{
263+
"project_id",
264+
"kms_key_id",
265+
"ssh_key_name",
266+
}
267+
268+
for _, v := range immutableArgs {
269+
if d.HasChange(v) {
270+
return fmt.Errorf("argument `%s` cannot be changed", v)
271+
}
272+
}
273+
274+
if d.HasChange("description") {
275+
request := ssm.NewUpdateDescriptionRequest()
276+
request.SecretName = &secretName
277+
278+
if v, ok := d.GetOk("description"); ok {
279+
request.Description = helper.String(v.(string))
280+
}
281+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
282+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseSsmClient().UpdateDescription(request)
283+
if e != nil {
284+
return retryError(e)
285+
} else {
286+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
287+
}
288+
return nil
289+
})
290+
if err != nil {
291+
log.Printf("[CRITAL]%s update ssm sshKeyPairSecret failed, reason:%+v", logId, err)
292+
return err
293+
}
294+
}
295+
296+
if d.HasChange("status") {
297+
service := SsmService{client: meta.(*TencentCloudClient).apiV3Conn}
298+
299+
if v, ok := d.GetOk("status"); ok {
300+
status := v.(string)
301+
if status == "Disabled" {
302+
err := service.DisableSecret(ctx, secretName)
303+
if err != nil {
304+
return err
305+
}
306+
} else {
307+
err := service.EnableSecret(ctx, secretName)
308+
if err != nil {
309+
return err
310+
}
311+
}
312+
}
313+
}
314+
315+
return resourceTencentCloudSsmSshKeyPairSecretRead(d, meta)
316+
}
317+
318+
func resourceTencentCloudSsmSshKeyPairSecretDelete(d *schema.ResourceData, meta interface{}) error {
319+
defer logElapsed("resource.tencentcloud_ssm_ssh_key_pair_secret.delete")()
320+
defer inconsistentCheck(d, meta)()
321+
322+
logId := getLogId(contextNil)
323+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
324+
325+
service := SsmService{client: meta.(*TencentCloudClient).apiV3Conn}
326+
secretName := d.Id()
327+
328+
// disable before destroy
329+
err := service.DisableSecret(ctx, secretName)
330+
if err != nil {
331+
return err
332+
}
333+
334+
var cleanSSHKey *bool
335+
336+
if v, ok := d.GetOkExists("clean_ssh_key"); ok {
337+
cleanSSHKey = helper.Bool(v.(bool))
338+
}
339+
340+
if err := service.DeleteSsmSshKeyPairSecretById(ctx, secretName, cleanSSHKey); err != nil {
341+
return err
342+
}
343+
344+
return nil
345+
}

0 commit comments

Comments
 (0)