Skip to content

Commit

Permalink
Merge pull request #24787 from ZeePal/main
Browse files Browse the repository at this point in the history
Added custom key stores for aws_kms_key & custom key store data source
  • Loading branch information
johnsonaj committed Sep 29, 2022
2 parents aeb1a16 + d38310e commit a903b30
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 13 deletions.
7 changes: 7 additions & 0 deletions .changelog/24787.txt
@@ -0,0 +1,7 @@
```release-note:new-data-source
aws_kms_custom_key_store
```

```release-note:enhancement
resource/aws_kms_key: Add `custom_key_store_id` attribute
```
13 changes: 7 additions & 6 deletions internal/provider/provider.go
Expand Up @@ -719,12 +719,13 @@ func New(_ context.Context) (*schema.Provider, error) {
"aws_kinesis_stream": kinesis.DataSourceStream(),
"aws_kinesis_stream_consumer": kinesis.DataSourceStreamConsumer(),

"aws_kms_alias": kms.DataSourceAlias(),
"aws_kms_ciphertext": kms.DataSourceCiphertext(),
"aws_kms_key": kms.DataSourceKey(),
"aws_kms_public_key": kms.DataSourcePublicKey(),
"aws_kms_secret": kms.DataSourceSecret(),
"aws_kms_secrets": kms.DataSourceSecrets(),
"aws_kms_alias": kms.DataSourceAlias(),
"aws_kms_ciphertext": kms.DataSourceCiphertext(),
"aws_kms_custom_key_store": kms.DataSourceCustomKeyStore(),
"aws_kms_key": kms.DataSourceKey(),
"aws_kms_public_key": kms.DataSourcePublicKey(),
"aws_kms_secret": kms.DataSourceSecret(),
"aws_kms_secrets": kms.DataSourceSecrets(),

"aws_lakeformation_data_lake_settings": lakeformation.DataSourceDataLakeSettings(),
"aws_lakeformation_permissions": lakeformation.DataSourcePermissions(),
Expand Down
5 changes: 4 additions & 1 deletion internal/service/kms/custom_key_store.go
Expand Up @@ -89,7 +89,10 @@ func resourceCustomKeyStoreCreate(ctx context.Context, d *schema.ResourceData, m
func resourceCustomKeyStoreRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).KMSConn

out, err := FindCustomKeyStoreByID(ctx, conn, d.Id())
in := &kms.DescribeCustomKeyStoresInput{
CustomKeyStoreId: aws.String(d.Id()),
}
out, err := FindCustomKeyStoreByID(ctx, conn, in)

if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] KMS CustomKeyStore (%s) not found, removing from state", d.Id())
Expand Down
86 changes: 86 additions & 0 deletions internal/service/kms/custom_key_store_data_source.go
@@ -0,0 +1,86 @@
package kms

import (
"context"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/kms"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/create"
"github.com/hashicorp/terraform-provider-aws/names"
)

func DataSourceCustomKeyStore() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceCustomKeyStoreRead,
Schema: map[string]*schema.Schema{
"custom_key_store_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ConflictsWith: []string{"custom_key_store_name"},
},
"custom_key_store_name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ConflictsWith: []string{"custom_key_store_id"},
},
"cloud_hsm_cluster_id": {
Type: schema.TypeString,
Computed: true,
},
"connection_state": {
Type: schema.TypeString,
Computed: true,
},
"creation_date": {
Type: schema.TypeString,
Computed: true,
},
"trust_anchor_certificate": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

const (
DSNameCustomKeyStore = "Custom Key Store"
)

func dataSourceCustomKeyStoreRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).KMSConn

input := &kms.DescribeCustomKeyStoresInput{}

var ksID string
if v, ok := d.GetOk("custom_key_store_id"); ok {
input.CustomKeyStoreId = aws.String(v.(string))
ksID = v.(string)
}
if v, ok := d.GetOk("custom_key_store_name"); ok {
input.CustomKeyStoreName = aws.String(v.(string))
ksID = v.(string)
}

keyStore, err := FindCustomKeyStoreByID(ctx, conn, input)

if err != nil {
return create.DiagError(names.KMS, create.ErrActionReading, DSNameCustomKeyStore, ksID, err)
}

d.SetId(aws.StringValue(keyStore.CustomKeyStoreId))
d.Set("custom_key_store_name", keyStore.CustomKeyStoreName)
d.Set("custom_key_store_id", keyStore.CustomKeyStoreId)
d.Set("cloud_hsm_cluster_id", keyStore.CloudHsmClusterId)
d.Set("connection_state", keyStore.ConnectionState)
d.Set("creation_date", keyStore.CreationDate.Format(time.RFC3339))
d.Set("trust_anchor_certificate", keyStore.TrustAnchorCertificate)

return nil
}
61 changes: 61 additions & 0 deletions internal/service/kms/custom_key_store_data_source_test.go
@@ -0,0 +1,61 @@
package kms_test

import (
"fmt"
"os"
"testing"

"github.com/aws/aws-sdk-go/service/kms"
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
)

func TestAccKMSCustomKeyStoreDataSource_basic(t *testing.T) {
if os.Getenv("CLOUD_HSM_CLUSTER_ID") == "" {
t.Skip("CLOUD_HSM_CLUSTER_ID environment variable not set")
}

if os.Getenv("TRUST_ANCHOR_CERTIFICATE") == "" {
t.Skip("TRUST_ANCHOR_CERTIFICATE environment variable not set")
}

resourceName := "aws_kms_custom_key_store.test"
dataSourceName := "data.aws_kms_custom_key_store.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
clusterId := os.Getenv("CLOUD_HSM_CLUSTER_ID")
trustAnchorCertificate := os.Getenv("TRUST_ANCHOR_CERTIFICATE")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, kms.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccCustomKeyStoreDataSourceConfig_basic(rName, clusterId, trustAnchorCertificate),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "custom_key_store_name", resourceName, "custom_key_store_name"),
resource.TestCheckResourceAttrPair(dataSourceName, "custom_key_store_id", resourceName, "id"),
resource.TestCheckResourceAttrPair(dataSourceName, "trust_anchor_certificate", resourceName, "trust_anchor_certificate"),
resource.TestCheckResourceAttrPair(dataSourceName, "cloud_hsm_cluster_id", resourceName, "cloud_hsm_cluster_id"),
),
},
},
})
}

func testAccCustomKeyStoreDataSourceConfig_basic(rName, clusterId, anchorCertificate string) string {
return fmt.Sprintf(`
resource "aws_kms_custom_key_store" "test" {
cloud_hsm_cluster_id = %[2]q
custom_key_store_name = %[1]q
key_store_password = "noplaintextpasswords1"
trust_anchor_certificate = file(%[3]q)
}
data "aws_kms_custom_key_store" "test" {
custom_key_store_id = aws_kms_custom_key_store.test.id
}
`, rName, clusterId, anchorCertificate)
}
12 changes: 10 additions & 2 deletions internal/service/kms/custom_key_store_test.go
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/kms"
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
Expand Down Expand Up @@ -159,7 +160,10 @@ func testAccCheckCustomKeyStoreDestroy(s *terraform.State) error {
continue
}

_, err := tfkms.FindCustomKeyStoreByID(ctx, conn, rs.Primary.ID)
in := &kms.DescribeCustomKeyStoresInput{
CustomKeyStoreId: aws.String(rs.Primary.ID),
}
_, err := tfkms.FindCustomKeyStoreByID(ctx, conn, in)

if tfresource.NotFound(err) {
continue
Expand All @@ -184,7 +188,11 @@ func testAccCheckCustomKeyStoreExists(name string, customkeystore *kms.CustomKey

conn := acctest.Provider.Meta().(*conns.AWSClient).KMSConn
ctx := context.Background()
resp, err := tfkms.FindCustomKeyStoreByID(ctx, conn, rs.Primary.ID)

in := &kms.DescribeCustomKeyStoresInput{
CustomKeyStoreId: aws.String(rs.Primary.ID),
}
resp, err := tfkms.FindCustomKeyStoreByID(ctx, conn, in)

if err != nil {
return create.Error(names.KMS, create.ErrActionCheckingExistence, tfkms.ResNameCustomKeyStore, rs.Primary.ID, err)
Expand Down
5 changes: 1 addition & 4 deletions internal/service/kms/find.go
Expand Up @@ -41,10 +41,7 @@ func FindAliasByName(conn *kms.KMS, name string) (*kms.AliasListEntry, error) {
return output, nil
}

func FindCustomKeyStoreByID(ctx context.Context, conn *kms.KMS, id string) (*kms.CustomKeyStoresListEntry, error) {
in := &kms.DescribeCustomKeyStoresInput{
CustomKeyStoreId: aws.String(id),
}
func FindCustomKeyStoreByID(ctx context.Context, conn *kms.KMS, in *kms.DescribeCustomKeyStoresInput) (*kms.CustomKeyStoresListEntry, error) {
out, err := conn.DescribeCustomKeyStoresWithContext(ctx, in)

if tfawserr.ErrCodeEquals(err, kms.ErrCodeCustomKeyStoreNotFoundException) {
Expand Down
12 changes: 12 additions & 0 deletions internal/service/kms/key.go
Expand Up @@ -40,6 +40,12 @@ func ResourceKey() *schema.Resource {
Optional: true,
Default: false,
},
"custom_key_store_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 22),
},
"customer_master_key_spec": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -121,6 +127,11 @@ func resourceKeyCreate(d *schema.ResourceData, meta interface{}) error {
input.Policy = aws.String(v.(string))
}

if v, ok := d.GetOk("custom_key_store_id"); ok {
input.Origin = aws.String(kms.OriginTypeAwsCloudhsm)
input.CustomKeyStoreId = aws.String(v.(string))
}

if len(tags) > 0 {
input.Tags = Tags(tags.IgnoreAWS())
}
Expand Down Expand Up @@ -192,6 +203,7 @@ func resourceKeyRead(d *schema.ResourceData, meta interface{}) error {
}

d.Set("arn", key.metadata.Arn)
d.Set("custom_key_store_id", key.metadata.CustomKeyStoreId)
d.Set("customer_master_key_spec", key.metadata.CustomerMasterKeySpec)
d.Set("description", key.metadata.Description)
d.Set("enable_key_rotation", key.rotation)
Expand Down
34 changes: 34 additions & 0 deletions website/docs/d/kms_custom_key_store.html.markdown
@@ -0,0 +1,34 @@
---
subcategory: "KMS (Key Management)"
layout: "aws"
page_title: "AWS: aws_kms_custom_key_store"
description: |-
Get information on a AWS Key Management Service (KMS) Custom Key Store
---

# Data Source: aws_kms_custom_key_store

Use this data source to get the metadata KMS custom key store.
By using this data source, you can reference KMS custom key store
without having to hard code the ID as input.

## Example Usage

```terraform
data "aws_kms_custom_key_store" "keystore" {
custom_key_store_name = "my_cloudhsm"
}
```

## Argument Reference

* `custom_key_store_id` - (Optional) The ID for the custom key store.
* `custom_key_store_name` - (Optional) The user-specified friendly name for the custom key store.

## Attributes Reference

* `id` - The ID for the custom key store.
* `cloudhsm_cluster_id` - ID for the CloudHSM cluster that is associated with the custom key store.
* `connection_state` - Indicates whether the custom key store is connected to its CloudHSM cluster.
* `creation_date` - The date and time when the custom key store was created.
* `trust_anchor_certificate` - The trust anchor certificate of the associated CloudHSM cluster.
1 change: 1 addition & 0 deletions website/docs/r/kms_key.html.markdown
Expand Up @@ -26,6 +26,7 @@ The following arguments are supported:
* `description` - (Optional) The description of the key as viewed in AWS console.
* `key_usage` - (Optional) Specifies the intended use of the key. Valid values: `ENCRYPT_DECRYPT`, `SIGN_VERIFY`, or `GENERATE_VERIFY_MAC`.
Defaults to `ENCRYPT_DECRYPT`.
* `custom_key_store_id` - (Optional) ID of the KMS [Custom Key Store](https://docs.aws.amazon.com/kms/latest/developerguide/create-cmk-keystore.html) where the key will be stored instead of KMS (eg CloudHSM).
* `customer_master_key_spec` - (Optional) Specifies whether the key contains a symmetric key or an asymmetric key pair and the encryption algorithms or signing algorithms that the key supports.
Valid values: `SYMMETRIC_DEFAULT`, `RSA_2048`, `RSA_3072`, `RSA_4096`, `HMAC_256`, `ECC_NIST_P256`, `ECC_NIST_P384`, `ECC_NIST_P521`, or `ECC_SECG_P256K1`. Defaults to `SYMMETRIC_DEFAULT`. For help with choosing a key spec, see the [AWS KMS Developer Guide](https://docs.aws.amazon.com/kms/latest/developerguide/symm-asymm-choose.html).
* `policy` - (Optional) A valid policy JSON document. Although this is a key policy, not an IAM policy, an [`aws_iam_policy_document`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document), in the form that designates a principal, can be used. For more information about building policy documents with Terraform, see the [AWS IAM Policy Document Guide](https://learn.hashicorp.com/terraform/aws/iam-policy).
Expand Down

0 comments on commit a903b30

Please sign in to comment.