Skip to content
Open
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/45514.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-list-resource
aws_kms_key
```
28 changes: 28 additions & 0 deletions internal/errs/fwdiag/diags.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/list"
sdkdiag "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices"
)

// DiagnosticsError returns an error containing all Diagnostic with SeverityError
Expand Down Expand Up @@ -71,6 +73,32 @@ func NewListResultErrorDiagnostic(err error) list.ListResult {
}
}

func NewListResultSDKDiagnostics(diags sdkdiag.Diagnostics) list.ListResult {
return list.ListResult{
Diagnostics: FromSDKDiagnostics(diags),
}
}

func FromSDKDiagnostics(diags sdkdiag.Diagnostics) diag.Diagnostics {
return tfslices.ApplyToAll(diags, FromSDKDiagnostic)
}

func FromSDKDiagnostic(d sdkdiag.Diagnostic) diag.Diagnostic {
switch d.Severity {
case sdkdiag.Error:
return diag.NewErrorDiagnostic(
d.Summary,
d.Detail,
)
case sdkdiag.Warning:
return diag.NewWarningDiagnostic(
d.Summary,
d.Detail,
)
}
return nil
}

func AsError[T any](x T, diags diag.Diagnostics) (T, error) {
return x, DiagnosticsError(diags)
}
Expand Down
91 changes: 91 additions & 0 deletions internal/service/kms/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/aws/aws-sdk-go-v2/service/kms"
awstypes "github.com/aws/aws-sdk-go-v2/service/kms/types"
awspolicy "github.com/hashicorp/awspolicyequivalence"
"github.com/hashicorp/terraform-plugin-framework/list"
listschema "github.com/hashicorp/terraform-plugin-framework/list/schema"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
Expand All @@ -22,11 +24,14 @@ import (
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/enum"
"github.com/hashicorp/terraform-provider-aws/internal/errs"
"github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag"
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
"github.com/hashicorp/terraform-provider-aws/internal/framework"
"github.com/hashicorp/terraform-provider-aws/internal/logging"
"github.com/hashicorp/terraform-provider-aws/internal/sdkv2"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
inttypes "github.com/hashicorp/terraform-provider-aws/internal/types"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
"github.com/hashicorp/terraform-provider-aws/names"
)
Expand Down Expand Up @@ -772,3 +777,89 @@ func waitKeyStatePropagated(ctx context.Context, conn *kms.Client, keyID string,

return tfresource.WaitUntil(ctx, timeout, checkFunc, opts)
}

// @SDKListResource("aws_kms_key")
func keyResourceAsListResource() inttypes.ListResourceForSDK {
l := keyListResource{}
l.SetResourceSchema(resourceKey())
return &l
}

type keyListResource struct {
framework.ResourceWithConfigure
framework.ListResourceWithSDKv2Resource
framework.ListResourceWithSDKv2Tags
}

type keyListResourceModel struct {
framework.WithRegionModel
}

func (l *keyListResource) ListResourceConfigSchema(ctx context.Context, request list.ListResourceSchemaRequest, response *list.ListResourceSchemaResponse) {
response.Schema = listschema.Schema{
Attributes: map[string]listschema.Attribute{},
Blocks: map[string]listschema.Block{},
}
}

func (l *keyListResource) List(ctx context.Context, request list.ListRequest, stream *list.ListResultsStream) {
var query keyListResourceModel
if request.Config.Raw.IsKnown() && !request.Config.Raw.IsNull() {
if diags := request.Config.Get(ctx, &query); diags.HasError() {
stream.Results = list.ListResultsStreamDiagnostics(diags)
return
}
}

awsClient := l.Meta()
conn := awsClient.KMSClient(ctx)

tflog.Info(ctx, "Listing KMS keys")
stream.Results = func(yield func(list.ListResult) bool) {
var input kms.ListKeysInput
pages := kms.NewListKeysPaginator(conn, &input)
for pages.HasMorePages() {
page, err := pages.NextPage(ctx)
if err != nil {
result := fwdiag.NewListResultErrorDiagnostic(err)
yield(result)
return
}

for _, key := range page.Keys {
id := aws.ToString(key.KeyId)
ctx := tflog.SetField(ctx, logging.ResourceAttributeKey(names.AttrID), id)

result := request.NewListResult(ctx)

rd := l.ResourceData()
rd.SetId(id)

tflog.Info(ctx, "Reading KMS key")
diags := resourceKeyRead(ctx, rd, awsClient)
if diags.HasError() || rd.Id() == "" {
// Resource can't be read or is logically deleted.
continue
}

if err := l.SetTags(ctx, awsClient, rd); err != nil {
result = fwdiag.NewListResultErrorDiagnostic(err)
yield(result)
return
}

result.DisplayName = id

l.SetResult(ctx, awsClient, request.IncludeResource, &result, rd)
if result.Diagnostics.HasError() {
yield(result)
return
}

if !yield(result) {
return
}
}
}
}
}
66 changes: 66 additions & 0 deletions internal/service/kms/key_list_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package kms_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/config"
sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
"github.com/hashicorp/terraform-plugin-testing/querycheck"
"github.com/hashicorp/terraform-plugin-testing/statecheck"
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
"github.com/hashicorp/terraform-plugin-testing/tfversion"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
tfquerycheck "github.com/hashicorp/terraform-provider-aws/internal/acctest/querycheck"
tfstatecheck "github.com/hashicorp/terraform-provider-aws/internal/acctest/statecheck"
"github.com/hashicorp/terraform-provider-aws/names"
)

func TestAccKMSKey_List_basic(t *testing.T) {
ctx := acctest.Context(t)
resourceName1 := "aws_kms_key.test[0]"
resourceName2 := "aws_kms_key.test[1]"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
identity1 := tfstatecheck.Identity()
identity2 := tfstatecheck.Identity()

acctest.ParallelTest(ctx, t, resource.TestCase{
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.SkipBelow(tfversion.Version1_14_0),
},
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.SSMServiceID),
CheckDestroy: testAccCheckKeyDestroy(ctx),
Steps: []resource.TestStep{
{
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
ConfigDirectory: config.StaticDirectory("testdata/Key/list_basic/"),
ConfigVariables: config.Variables{
acctest.CtRName: config.StringVariable(rName),
},
ConfigStateChecks: []statecheck.StateCheck{
identity1.GetIdentity(resourceName1),
statecheck.ExpectKnownValue(resourceName1, tfjsonpath.New(names.AttrDescription), knownvalue.StringExact(rName+"-0")),
identity2.GetIdentity(resourceName2),
statecheck.ExpectKnownValue(resourceName2, tfjsonpath.New(names.AttrDescription), knownvalue.StringExact(rName+"-1")),
},
},
{
Query: true,
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
ConfigDirectory: config.StaticDirectory("testdata/Key/list_basic/"),
ConfigVariables: config.Variables{
acctest.CtRName: config.StringVariable(rName),
},
QueryResultChecks: []querycheck.QueryResultCheck{
tfquerycheck.ExpectIdentityFunc("aws_kms_key.test", identity1.Checks()),
tfquerycheck.ExpectIdentityFunc("aws_kms_key.test", identity2.Checks()),
},
},
},
})
}
17 changes: 17 additions & 0 deletions internal/service/kms/service_package_gen.go

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

15 changes: 15 additions & 0 deletions internal/service/kms/testdata/Key/list_basic/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

resource "aws_kms_key" "test" {
count = 2

description = "${var.rName}-${count.index}"
deletion_window_in_days = 7
}

variable "rName" {
description = "Name for resource"
type = string
nullable = false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

list "aws_kms_key" "test" {
provider = aws
}
25 changes: 25 additions & 0 deletions website/docs/list-resources/kms_key.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
subcategory: "KMS (Key Management)"
layout: "aws"
page_title: "AWS: aws_kms_key"
description: |-
Lists single-Region or multi-Region primary KMS keys.
---

# List Resource: aws_kms_key

Lists single-Region or multi-Region primary KMS keys.

## Example Usage

```terraform
list "aws_kms_key" "example" {
provider = aws
}
```

## Argument Reference

This list resource supports the following arguments:

* `region` - (Optional) Region to query. Defaults to provider region.
Loading