From 8e130b15e4e9739dfa0943981d187ffd38a3f24b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 22 May 2017 09:46:18 -0400 Subject: [PATCH] Add 'aws_kms_ciphertext' data source. (#14691) --- .../aws/data_source_aws_kms_ciphertext.go | 66 +++++++++ .../data_source_aws_kms_ciphertext_test.go | 136 ++++++++++++++++++ builtin/providers/aws/provider.go | 3 +- .../aws/d/kms_ciphertext.html.markdown | 48 +++++++ website/source/layouts/aws.erb | 10 +- 5 files changed, 259 insertions(+), 4 deletions(-) create mode 100644 builtin/providers/aws/data_source_aws_kms_ciphertext.go create mode 100644 builtin/providers/aws/data_source_aws_kms_ciphertext_test.go create mode 100644 website/source/docs/providers/aws/d/kms_ciphertext.html.markdown diff --git a/builtin/providers/aws/data_source_aws_kms_ciphertext.go b/builtin/providers/aws/data_source_aws_kms_ciphertext.go new file mode 100644 index 000000000..3f15965ca --- /dev/null +++ b/builtin/providers/aws/data_source_aws_kms_ciphertext.go @@ -0,0 +1,66 @@ +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 dataSourceAwsKmsCiphetext() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsKmsCiphetextRead, + + Schema: map[string]*schema.Schema{ + "plaintext": { + Type: schema.TypeString, + Required: true, + }, + + "key_id": { + Type: schema.TypeString, + Required: true, + }, + + "context": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "ciphertext_blob": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceAwsKmsCiphetextRead(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 +} diff --git a/builtin/providers/aws/data_source_aws_kms_ciphertext_test.go b/builtin/providers/aws/data_source_aws_kms_ciphertext_test.go new file mode 100644 index 000000000..f871acc03 --- /dev/null +++ b/builtin/providers/aws/data_source_aws_kms_ciphertext_test.go @@ -0,0 +1,136 @@ +package aws + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccDataSourceAwsKmsCiphertext_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsKmsCiphertextConfig_basic, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.aws_kms_ciphertext.foo", "ciphertext_blob"), + ), + }, + }, + }) +} + +func TestAccDataSourceAwsKmsCiphertext_validate(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsKmsCiphertextConfig_validate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.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 TestAccDataSourceAwsKmsCiphertext_validate_withContext(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsKmsCiphertextConfig_validate_withContext, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.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"), + ), + }, + }, + }) +} + +const testAccDataSourceAwsKmsCiphertextConfig_basic = ` +provider "aws" { + 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" { + key_id = "${aws_kms_key.foo.key_id}" + + plaintext = "Super secret data" +} +` + +const testAccDataSourceAwsKmsCiphertextConfig_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 = "${data.aws_kms_ciphertext.foo.ciphertext_blob}" + } +} +` + +const testAccDataSourceAwsKmsCiphertextConfig_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 = "${data.aws_kms_ciphertext.foo.ciphertext_blob}" + + context { + name = "value" + } + } +} +` diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index bba070e39..94ab3429a 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -183,14 +183,15 @@ func Provider() terraform.ResourceProvider { "aws_eip": dataSourceAwsEip(), "aws_elb_hosted_zone_id": dataSourceAwsElbHostedZoneId(), "aws_elb_service_account": dataSourceAwsElbServiceAccount(), - "aws_kinesis_stream": dataSourceAwsKinesisStream(), "aws_iam_account_alias": dataSourceAwsIamAccountAlias(), "aws_iam_policy_document": dataSourceAwsIamPolicyDocument(), "aws_iam_role": dataSourceAwsIAMRole(), "aws_iam_server_certificate": dataSourceAwsIAMServerCertificate(), "aws_instance": dataSourceAwsInstance(), "aws_ip_ranges": dataSourceAwsIPRanges(), + "aws_kinesis_stream": dataSourceAwsKinesisStream(), "aws_kms_alias": dataSourceAwsKmsAlias(), + "aws_kms_ciphertext": dataSourceAwsKmsCiphetext(), "aws_kms_secret": dataSourceAwsKmsSecret(), "aws_partition": dataSourceAwsPartition(), "aws_prefix_list": dataSourceAwsPrefixList(), diff --git a/website/source/docs/providers/aws/d/kms_ciphertext.html.markdown b/website/source/docs/providers/aws/d/kms_ciphertext.html.markdown new file mode 100644 index 000000000..f27a5af47 --- /dev/null +++ b/website/source/docs/providers/aws/d/kms_ciphertext.html.markdown @@ -0,0 +1,48 @@ +--- +layout: "aws" +page_title: "AWS: aws_kms_ciphertext" +sidebar_current: "docs-aws-datasource-kms-ciphertext" +description: |- + Provides ciphertext encrypted using a KMS key +--- + +# aws\_kms\_ciphertext + +The KMS ciphertext data source allows you to encrypt plaintext into ciphertext +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 +} + +data "aws_kms_ciphertext" "oauth" { + key_id = "${aws_kms_key.oauth_config.key_id}" + plaintext = < > aws_db_instance + > aws_db_snapshot @@ -85,9 +86,6 @@ > aws_elb_service_account - > - aws_kinesis_stream - > aws_iam_account_alias @@ -106,9 +104,15 @@ > aws_ip_ranges + > + aws_kinesis_stream + > aws_kms_alias + > + aws_kms_ciphertext + > aws_kms_secret