Skip to content

Commit

Permalink
Merge pull request #32606 from hashicorp/f-aws_lightsail_key_pair-tags
Browse files Browse the repository at this point in the history
r/aws_lightsail_key_pair: tags
  • Loading branch information
johnsonaj authored Jul 20, 2023
2 parents 606873d + b813a8a commit 86562aa
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 27 deletions.
3 changes: 3 additions & 0 deletions .changelog/32606.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_lightsail_key_pair: Add `tags` attribute
```
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ func {{ .SetTagsOutFunc }}(ctx context.Context, tags []awstypes.{{ .TagType }})

{{- if ne .CreateTagsFunc "" }}
// {{ .CreateTagsFunc }} creates {{ .ServicePackage }} service tags for new resources.
func {{ .CreateTagsFunc }}(ctx context.Context, conn {{ .ClientType }}, identifier{{ if .TagResTypeElem }}, resourceType{{ end }} string, tags []*{{ .TagPackage }}.{{ .TagType }}) error {
func {{ .CreateTagsFunc }}(ctx context.Context, conn {{ .ClientType }}, identifier{{ if .TagResTypeElem }}, resourceType{{ end }} string, tags []awstypes.{{ .TagType }}) error {
if len(tags) == 0 {
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion internal/service/lightsail/generate.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

//go:generate go run ../../generate/tags/main.go -AWSSDKVersion=2 -ListTagsInIDElem=ResourceName -ServiceTagsSlice -TagInIDElem=ResourceName -UpdateTags
//go:generate go run ../../generate/tags/main.go -AWSSDKVersion=2 -ListTagsInIDElem=ResourceName -ServiceTagsSlice -TagInIDElem=ResourceName -UpdateTags -CreateTags
//go:generate go run ../../generate/servicepackage/main.go
// ONLY generate directives and package declaration! Do not add anything else to this file.

Expand Down
22 changes: 21 additions & 1 deletion internal/service/lightsail/key_pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,23 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/vault/helper/pgpkeys"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
"github.com/hashicorp/terraform-provider-aws/names"
)

const (
ResKeyPair = "KeyPair"
)

// @SDKResource("aws_lightsail_key_pair")
// @SDKResource("aws_lightsail_key_pair", name=KeyPair)
// @Tags(identifierAttribute="id")
func ResourceKeyPair() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceKeyPairCreate,
ReadWithoutTimeout: resourceKeyPairRead,
UpdateWithoutTimeout: resourceKeyPairUpdate,
DeleteWithoutTimeout: resourceKeyPairDelete,

Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -85,7 +90,10 @@ func ResourceKeyPair() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
names.AttrTags: tftags.TagsSchema(),
names.AttrTagsAll: tftags.TagsSchemaComputed(),
},
CustomizeDiff: verify.SetTagsDiff,
}
}

Expand All @@ -112,6 +120,7 @@ func resourceKeyPairCreate(ctx context.Context, d *schema.ResourceData, meta int
// creating new key
resp, err := conn.CreateKeyPair(ctx, &lightsail.CreateKeyPairInput{
KeyPairName: aws.String(kName),
Tags: getTagsIn(ctx),
})
if err != nil {
return sdkdiag.AppendErrorf(diags, "creating Lightsail Key Pair (%s): %s", kName, err)
Expand Down Expand Up @@ -160,6 +169,10 @@ func resourceKeyPairCreate(ctx context.Context, d *schema.ResourceData, meta int
d.SetId(kName)

op = resp.Operation

if err := createTags(ctx, conn, kName, getTagsIn(ctx)); err != nil {
return sdkdiag.AppendErrorf(diags, "creating Lightsail Key Pair (%s): %s", kName, err)
}
}

diag := expandOperations(ctx, conn, []types.Operation{*op}, "CreateKeyPair", ResKeyPair, kName)
Expand Down Expand Up @@ -192,9 +205,16 @@ func resourceKeyPairRead(ctx context.Context, d *schema.ResourceData, meta inter
d.Set("name", resp.KeyPair.Name)
d.Set("fingerprint", resp.KeyPair.Fingerprint)

setTagsOut(ctx, resp.KeyPair.Tags)

return diags
}

func resourceKeyPairUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
// Tags only.
return resourceKeyPairRead(ctx, d, meta)
}

func resourceKeyPairDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).LightsailClient(ctx)
Expand Down
124 changes: 119 additions & 5 deletions internal/service/lightsail/key_pair_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ func TestAccLightsailKeyPair_basic(t *testing.T) {
resourceName := "aws_lightsail_key_pair.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) },
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, strings.ToLower(lightsail.ServiceID))
testAccPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(lightsail.ServiceID)),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckKeyPairDestroy(ctx),
Expand Down Expand Up @@ -58,7 +62,11 @@ func TestAccLightsailKeyPair_publicKey(t *testing.T) {
}

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) },
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, strings.ToLower(lightsail.ServiceID))
testAccPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(lightsail.ServiceID)),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckKeyPairDestroy(ctx),
Expand Down Expand Up @@ -86,7 +94,11 @@ func TestAccLightsailKeyPair_encrypted(t *testing.T) {
resourceName := "aws_lightsail_key_pair.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) },
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, strings.ToLower(lightsail.ServiceID))
testAccPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(lightsail.ServiceID)),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckKeyPairDestroy(ctx),
Expand All @@ -110,7 +122,11 @@ func TestAccLightsailKeyPair_encrypted(t *testing.T) {
func TestAccLightsailKeyPair_namePrefix(t *testing.T) {
ctx := acctest.Context(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) },
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, strings.ToLower(lightsail.ServiceID))
testAccPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(lightsail.ServiceID)),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckKeyPairDestroy(ctx),
Expand All @@ -128,6 +144,79 @@ func TestAccLightsailKeyPair_namePrefix(t *testing.T) {
})
}

func TestAccLightsailKeyPair_tags(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resourceName := "aws_lightsail_key_pair.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, strings.ToLower(lightsail.ServiceID))
testAccPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(lightsail.ServiceID)),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckKeyPairDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccKeyPairConfig_tags1(rName, "key1", "value1"),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKeyPairExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"),
),
},
{
Config: testAccKeyPairConfig_tags2(rName, "key1", "value1", "key2", "value2"),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKeyPairExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"),
resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"),
),
},
{
Config: testAccKeyPairConfig_tags1(rName, "key2", "value2"),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKeyPairExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"),
),
},
},
})
}

func TestAccLightsailKeyPair_disappears(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resourceName := "aws_lightsail_key_pair.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, strings.ToLower(lightsail.ServiceID))
testAccPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(lightsail.ServiceID)),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckKeyPairDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccKeyPairConfig_basic(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKeyPairExists(ctx, resourceName),
acctest.CheckResourceDisappears(ctx, acctest.Provider, tflightsail.ResourceKeyPair(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccCheckKeyPairExists(ctx context.Context, n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down Expand Up @@ -189,7 +278,7 @@ func testAccCheckKeyPairDestroy(ctx context.Context) resource.TestCheckFunc {
func testAccKeyPairConfig_basic(lightsailName string) string {
return fmt.Sprintf(`
resource "aws_lightsail_key_pair" "test" {
name = "%s"
name = %[1]q
}
`, lightsailName)
}
Expand Down Expand Up @@ -226,6 +315,31 @@ resource "aws_lightsail_key_pair" "lightsail_key_pair_test_prefixed" {
`
}

func testAccKeyPairConfig_tags1(lightsailName, key1, value1 string) string {
return fmt.Sprintf(`
resource "aws_lightsail_key_pair" "test" {
name = %[1]q
tags = {
%[2]q = %[3]q
}
}
`, lightsailName, key1, value1)
}

func testAccKeyPairConfig_tags2(lightsailName, key1, value1, key2, value2 string) string {
return fmt.Sprintf(`
resource "aws_lightsail_key_pair" "test" {
name = %[1]q
tags = {
%[2]q = %[3]q
%[4]q = %[5]q
}
}
`, lightsailName, key1, value1, key2, value2)
}

const testKeyPairPubKey1 = `mQENBFXbjPUBCADjNjCUQwfxKL+RR2GA6pv/1K+zJZ8UWIF9S0lk7cVIEfJiprzzwiMwBS5cD0da
rGin1FHvIWOZxujA7oW0O2TUuatqI3aAYDTfRYurh6iKLC+VS+F7H+/mhfFvKmgr0Y5kDCF1j0T/
063QZ84IRGucR/X43IY7kAtmxGXH0dYOCzOe5UBX1fTn3mXGe2ImCDWBH7gOViynXmb6XNvXkP0f
Expand Down
4 changes: 4 additions & 0 deletions internal/service/lightsail/service_package_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions internal/service/lightsail/tags_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 11 additions & 19 deletions website/docs/r/lightsail_key_pair.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -47,32 +47,24 @@ resource "aws_lightsail_key_pair" "lg_key_pair" {

This resource supports the following arguments:

* `name` - (Optional) The name of the Lightsail Key Pair. If omitted, a unique
name will be generated by Terraform
* `pgp_key` – (Optional) An optional PGP key to encrypt the resulting private
key material. Only used when creating a new key pair
* `public_key` - (Required) The public key material. This public key will be
imported into Lightsail
* `name` - (Optional) The name of the Lightsail Key Pair. If omitted, a unique name will be generated by Terraform
* `pgp_key` – (Optional) An optional PGP key to encrypt the resulting private key material. Only used when creating a new key pair
* `public_key` - (Required) The public key material. This public key will be imported into Lightsail
* `tags` - (Optional) A map of tags to assign to the collection. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.

~> **NOTE:** a PGP key is not required, however it is strongly encouraged.
Without a PGP key, the private key material will be stored in state unencrypted.
`pgp_key` is ignored if `public_key` is supplied.
~> **NOTE:** a PGP key is not required, however it is strongly encouraged. Without a PGP key, the private key material will be stored in state unencrypted.`pgp_key` is ignored if `public_key` is supplied.

## Attribute Reference

This resource exports the following attributes in addition to the arguments above:

* `id` - The name used for this key pair
* `arn` - The ARN of the Lightsail key pair
* `id` - The name used for this key pair.
* `arn` - The ARN of the Lightsail key pair.
* `encrypted_fingerprint` - The MD5 public key fingerprint for the encrypted private key.
* `encrypted_private_key` – the private key material, base 64 encoded and encrypted with the given `pgp_key`. This is only populated when creating a new key and `pgp_key` is supplied.
* `fingerprint` - The MD5 public key fingerprint as specified in section 4 of RFC 4716.
* `public_key` - the public key, base64 encoded
* `private_key` - the private key, base64 encoded. This is only populated
when creating a new key, and when no `pgp_key` is provided
* `encrypted_private_key` – the private key material, base 64 encoded and
encrypted with the given `pgp_key`. This is only populated when creating a new
key and `pgp_key` is supplied
* `encrypted_fingerprint` - The MD5 public key fingerprint for the encrypted
private key
* `public_key` - the public key, base64 encoded.
* `private_key` - the private key, base64 encoded. This is only populated when creating a new key, and when no `pgp_key` is provided.

## Import

Expand Down

0 comments on commit 86562aa

Please sign in to comment.