Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws_kms_ciphertext into new resource keeping datasource #6993

Merged
merged 6 commits into from
Mar 26, 2019
Merged
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
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ func Provider() terraform.ResourceProvider {
"aws_kms_alias": resourceAwsKmsAlias(),
"aws_kms_grant": resourceAwsKmsGrant(),
"aws_kms_key": resourceAwsKmsKey(),
"aws_kms_ciphertext": resourceAwsKmsCiphertext(),
"aws_lambda_function": resourceAwsLambdaFunction(),
"aws_lambda_event_source_mapping": resourceAwsLambdaEventSourceMapping(),
"aws_lambda_alias": resourceAwsLambdaAlias(),
Expand Down
86 changes: 86 additions & 0 deletions aws/resource_aws_kms_ciphertext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package aws

import (
"encoding/base64"
"log"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/kms"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsKmsCiphertext() *schema.Resource {

return &schema.Resource{
Create: resourceAwsKmsCiphertextCreate,
Read: resourceAwsKmsCiphertextRead,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I believe we can replace the empty custom functions with schema.Noop 👍

Delete: resourceAwsKmsCiphertextDelete,

Schema: map[string]*schema.Schema{
"plaintext": {
cperilla-rival marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeString,
Required: true,
ForceNew: true,
Sensitive: true,
},

"key_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"context": {
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
ForceNew: true,
},

"ciphertext_blob": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceAwsKmsCiphertextCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).kmsconn

d.SetId(time.Now().UTC().String())

req := &kms.EncryptInput{
KeyId: aws.String(d.Get("key_id").(string)),
Plaintext: []byte(d.Get("plaintext").(string)),
}

if ec := d.Get("context"); ec != nil {
req.EncryptionContext = stringMapToPointers(ec.(map[string]interface{}))
}

log.Printf("[DEBUG] KMS encrypt for key: %s", d.Get("key_id").(string))
resp, err := conn.Encrypt(req)
if err != nil {
return err
}

d.Set("ciphertext_blob", base64.StdEncoding.EncodeToString(resp.CiphertextBlob))

return nil
}

func resourceAwsKmsCiphertextDelete(d *schema.ResourceData, meta interface{}) error {
d.SetId("")
return nil
}

func resourceAwsKmsCiphertextRead(d *schema.ResourceData, meta interface{}) error {
// If the input has changed, generate a new ciphertext_blob
// This should never be the case since ForceNew set on all input.
if d.HasChange("plaintext") || d.HasChange("key_id") || d.HasChange("context") {
return resourceAwsKmsCiphertextCreate(d, meta)
}
return nil
}
136 changes: 136 additions & 0 deletions aws/resource_aws_kms_ciphertext_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package aws

import (
"testing"

"github.com/hashicorp/terraform/helper/resource"
)

func TestAccResourceAwsKmsCiphertext_basic(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccResourceAwsKmsCiphertextConfig_basic,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(
"aws_kms_ciphertext.foo", "ciphertext_blob"),
),
},
},
})
}

func TestAccResourceAwsKmsCiphertext_validate(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccResourceAwsKmsCiphertextConfig_validate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(
"aws_kms_ciphertext.foo", "ciphertext_blob"),
resource.TestCheckResourceAttrSet(
"data.aws_kms_secret.foo", "plaintext"),
resource.TestCheckResourceAttr(
"data.aws_kms_secret.foo", "plaintext", "Super secret data"),
),
},
},
})
}

func TestAccResourceAwsKmsCiphertext_validate_withContext(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccResourceAwsKmsCiphertextConfig_validate_withContext,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(
"aws_kms_ciphertext.foo", "ciphertext_blob"),
resource.TestCheckResourceAttrSet(
"aws_kms_secret.foo", "plaintext"),
resource.TestCheckResourceAttr(
"aws_kms_secret.foo", "plaintext", "Super secret data"),
),
},
},
})
}

const testAccResourceAwsKmsCiphertextConfig_basic = `
provider "aws" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Including the provider configurations for most acceptance testing is extraneous

region = "us-west-2"
}

resource "aws_kms_key" "foo" {
description = "tf-test-acc-data-source-aws-kms-ciphertext-basic"
is_enabled = true
}

data "aws_kms_ciphertext" "foo" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These test configurations should reference the resource not data source.

key_id = "${aws_kms_key.foo.key_id}"

plaintext = "Super secret data"
}
`

const testAccResourceAwsKmsCiphertextConfig_validate = `
provider "aws" {
region = "us-west-2"
}

resource "aws_kms_key" "foo" {
description = "tf-test-acc-data-source-aws-kms-ciphertext-validate"
is_enabled = true
}

data "aws_kms_ciphertext" "foo" {
key_id = "${aws_kms_key.foo.key_id}"

plaintext = "Super secret data"
}

data "aws_kms_secret" "foo" {
secret {
name = "plaintext"
payload = "${aws_kms_ciphertext.foo.ciphertext_blob}"
}
}
`

const testAccResourceAwsKmsCiphertextConfig_validate_withContext = `
provider "aws" {
region = "us-west-2"
}

resource "aws_kms_key" "foo" {
description = "tf-test-acc-data-source-aws-kms-ciphertext-validate-with-context"
is_enabled = true
}

data "aws_kms_ciphertext" "foo" {
key_id = "${aws_kms_key.foo.key_id}"

plaintext = "Super secret data"

context {
name = "value"
}
}

data "aws_kms_secret" "foo" {
secret {
name = "plaintext"
payload = "${aws_kms_ciphertext.foo.ciphertext_blob}"

context {
name = "value"
}
}
}
`
4 changes: 4 additions & 0 deletions website/aws.erb
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,10 @@
<a href="/docs/providers/aws/r/kms_grant.html">aws_kms_grant</a>
</li>

<li<%= sidebar_current("docs-aws-resource-kms-ciphertext") %>>
<a href="/docs/providers/aws/r/kms_ciphertext.html">aws_kms_ciphertext</a>
</li>

<li<%= sidebar_current("docs-aws-resource-kms-key") %>>
<a href="/docs/providers/aws/r/kms_key.html">aws_kms_key</a>
</li>
Expand Down
49 changes: 49 additions & 0 deletions website/docs/r/kms_ciphertext.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
layout: "aws"
page_title: "AWS: aws_kms_ciphertext"
sidebar_current: "docs-aws-resource-kms-ciphertext"
description: |-
Provides ciphertext encrypted using a KMS key
---

# Resource: aws_kms_ciphertext

The KMS ciphertext resource allows you to encrypt plaintext into ciphertext
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We should include a cross referencing link to the aws_kms_ciphertext data source and explain the difference between the two.

by using an AWS KMS customer master key.

~> **Note:** All arguments including the plaintext be stored in the raw state as plain-text.
[Read more about sensitive data in state](/docs/state/sensitive-data.html).

## Example Usage

```hcl
resource "aws_kms_key" "oauth_config" {
description = "oauth config"
is_enabled = true
}

resource "aws_kms_ciphertext" "oauth" {
key_id = "${aws_kms_key.oauth_config.key_id}"

plaintext = <<EOF
{
"client_id": "e587dbae22222f55da22",
"client_secret": "8289575d00000ace55e1815ec13673955721b8a5"
}
EOF
}
```

## Argument Reference

The following arguments are supported:

* `plaintext` - (Required) Data to be encrypted. Note that this may show up in logs, and it will be stored in the state file.
* `key_id` - (Required) Globally unique key ID for the customer master key.
* `context` - (Optional) An optional mapping that makes up the encryption context.

## Attributes Reference

All of the argument attributes are also exported as result attributes.

* `ciphertext_blob` - Base64 encoded ciphertext