mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-01 16:21:06 +00:00
Adds google_kms_secret data source (#741)
* Create google_kms_secret datasource * Create google_kms_secret datasource documentation * Remove duplicated code * Create acceptance test * Fix indentation * Add documentation to sidebar * Update Cloud SDK link in docs * Oxford comma * Rename variable to make it clear which resource is under test * Update test to use utils from provider_test
This commit is contained in:
parent
2e9933be44
commit
18a6255064
67
google/data_source_google_kms_secret.go
Normal file
67
google/data_source_google_kms_secret.go
Normal file
@ -0,0 +1,67 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"google.golang.org/api/cloudkms/v1"
|
||||
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
func dataSourceGoogleKmsSecret() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Read: dataSourceGoogleKmsSecretRead,
|
||||
Schema: map[string]*schema.Schema{
|
||||
"crypto_key": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"ciphertext": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"plaintext": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceGoogleKmsSecretRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
cryptoKeyId, err := parseKmsCryptoKeyId(d.Get("crypto_key").(string), config)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ciphertext := d.Get("ciphertext").(string)
|
||||
|
||||
kmsDecryptRequest := &cloudkms.DecryptRequest{
|
||||
Ciphertext: ciphertext,
|
||||
}
|
||||
|
||||
decryptResponse, err := config.clientKms.Projects.Locations.KeyRings.CryptoKeys.Decrypt(cryptoKeyId.cryptoKeyId(), kmsDecryptRequest).Do()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error decrypting ciphertext: %s", err)
|
||||
}
|
||||
|
||||
plaintext, err := base64.StdEncoding.DecodeString(decryptResponse.Plaintext)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error decoding base64 response: %s", err)
|
||||
}
|
||||
|
||||
log.Printf("[INFO] Successfully decrypted ciphertext: %s", ciphertext)
|
||||
|
||||
d.Set("plaintext", string(plaintext[:]))
|
||||
d.SetId(time.Now().UTC().String())
|
||||
|
||||
return nil
|
||||
}
|
96
google/data_source_google_kms_secret_test.go
Normal file
96
google/data_source_google_kms_secret_test.go
Normal file
@ -0,0 +1,96 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"google.golang.org/api/cloudkms/v1"
|
||||
"log"
|
||||
)
|
||||
|
||||
func TestAccGoogleKmsSecret_basic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
projectOrg := getTestOrgFromEnv(t)
|
||||
projectBillingAccount := getTestBillingAccountFromEnv(t)
|
||||
|
||||
projectId := "terraform-" + acctest.RandString(10)
|
||||
keyRingName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
|
||||
cryptoKeyName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
|
||||
|
||||
plaintext := fmt.Sprintf("secret-%s", acctest.RandString(10))
|
||||
|
||||
// The first test creates resources needed to encrypt plaintext and produce ciphertext
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testGoogleKmsCryptoKey_basic(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName),
|
||||
Check: func(s *terraform.State) error {
|
||||
ciphertext, cryptoKeyId, err := testAccEncryptSecretDataWithCryptoKey(s, "google_kms_crypto_key.crypto_key", plaintext)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The second test asserts that the data source has the correct plaintext, given the created ciphertext
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testGoogleKmsSecret_datasource(cryptoKeyId.terraformId(), ciphertext),
|
||||
Check: resource.TestCheckResourceAttr("data.google_kms_secret.acceptance", "plaintext", plaintext),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccEncryptSecretDataWithCryptoKey(s *terraform.State, cryptoKeyResourceName, plaintext string) (string, *kmsCryptoKeyId, error) {
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
rs, ok := s.RootModule().Resources[cryptoKeyResourceName]
|
||||
if !ok {
|
||||
return "", nil, fmt.Errorf("Resource not found: %s", cryptoKeyResourceName)
|
||||
}
|
||||
|
||||
cryptoKeyId, err := parseKmsCryptoKeyId(rs.Primary.Attributes["id"], config)
|
||||
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
kmsEncryptRequest := &cloudkms.EncryptRequest{
|
||||
Plaintext: base64.StdEncoding.EncodeToString([]byte(plaintext)),
|
||||
}
|
||||
|
||||
encryptResponse, err := config.clientKms.Projects.Locations.KeyRings.CryptoKeys.Encrypt(cryptoKeyId.cryptoKeyId(), kmsEncryptRequest).Do()
|
||||
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("Error encrypting plaintext: %s", err)
|
||||
}
|
||||
|
||||
log.Printf("[INFO] Successfully encrypted plaintext and got ciphertext: %s", encryptResponse.Ciphertext)
|
||||
|
||||
return encryptResponse.Ciphertext, cryptoKeyId, nil
|
||||
}
|
||||
|
||||
func testGoogleKmsSecret_datasource(cryptoKeyTerraformId, ciphertext string) string {
|
||||
return fmt.Sprintf(`
|
||||
data "google_kms_secret" "acceptance" {
|
||||
crypto_key = "%s"
|
||||
ciphertext = "%s"
|
||||
}
|
||||
`, cryptoKeyTerraformId, ciphertext)
|
||||
}
|
@ -74,6 +74,7 @@ func Provider() terraform.ResourceProvider {
|
||||
"google_container_engine_versions": dataSourceGoogleContainerEngineVersions(),
|
||||
"google_active_folder": dataSourceGoogleActiveFolder(),
|
||||
"google_iam_policy": dataSourceGoogleIamPolicy(),
|
||||
"google_kms_secret": dataSourceGoogleKmsSecret(),
|
||||
"google_storage_object_signed_url": dataSourceGoogleSignedUrl(),
|
||||
},
|
||||
|
||||
|
93
website/docs/d/google_kms_secret.html.markdown
Normal file
93
website/docs/d/google_kms_secret.html.markdown
Normal file
@ -0,0 +1,93 @@
|
||||
---
|
||||
layout: "google"
|
||||
page_title: "Google: google_kms_secret"
|
||||
sidebar_current: "docs-google-kms-secret"
|
||||
description: |-
|
||||
Provides access to secret data encrypted with Google Cloud KMS
|
||||
---
|
||||
|
||||
# google\_kms\_secret
|
||||
|
||||
This data source allows you to use data encrypted with Google Cloud KMS
|
||||
within your resource definitions.
|
||||
|
||||
For more information see
|
||||
[the official documentation](https://cloud.google.com/kms/docs/encrypt-decrypt).
|
||||
|
||||
~> **NOTE**: Using this data provider will allow you to conceal secret data within your
|
||||
resource definitions, but it does not take care of protecting that data in the
|
||||
logging output, plan output, or state output. Please take care to secure your secret
|
||||
data outside of resource definitions.
|
||||
|
||||
## Example Usage
|
||||
|
||||
First, create a KMS KeyRing and CryptoKey using the resource definitions:
|
||||
|
||||
```hcl
|
||||
resource "google_kms_key_ring" "my_key_ring" {
|
||||
project = "my-project"
|
||||
name = "my-key-ring"
|
||||
location = "us-central1"
|
||||
}
|
||||
|
||||
resource "google_kms_crypto_key" "my_crypto_key" {
|
||||
name = "my-crypto-key"
|
||||
key_ring = "${google_kms_key_ring.my_key_ring.id}"
|
||||
}
|
||||
```
|
||||
|
||||
Next, use the [Cloud SDK](https://cloud.google.com/sdk/gcloud/reference/kms/encrypt) to encrypt some
|
||||
sensitive information:
|
||||
|
||||
```bash
|
||||
$ echo -n my-secret-password | gcloud kms encrypt \
|
||||
> --project my-project \
|
||||
> --location us-central1 \
|
||||
> --keyring my-key-ring \
|
||||
> --key my-crypto-key \
|
||||
> --plaintext-file - \
|
||||
> --ciphertext-file - \
|
||||
> | base64
|
||||
CiQAqD+xX4SXOSziF4a8JYvq4spfAuWhhYSNul33H85HnVtNQW4SOgDu2UZ46dQCRFl5MF6ekabviN8xq+F+2035ZJ85B+xTYXqNf4mZs0RJitnWWuXlYQh6axnnJYu3kDU=
|
||||
```
|
||||
|
||||
Finally, reference the encrypted ciphertext in your resource definitions:
|
||||
|
||||
```hcl
|
||||
data "google_kms_secret" "sql_user_password" {
|
||||
crypto_key = "${google_kms_crypto_key.my_crypto_key.id}"
|
||||
ciphertext = "CiQAqD+xX4SXOSziF4a8JYvq4spfAuWhhYSNul33H85HnVtNQW4SOgDu2UZ46dQCRFl5MF6ekabviN8xq+F+2035ZJ85B+xTYXqNf4mZs0RJitnWWuXlYQh6axnnJYu3kDU="
|
||||
}
|
||||
|
||||
resource "google_sql_database_instance" "master" {
|
||||
name = "master-instance"
|
||||
|
||||
settings {
|
||||
tier = "D0"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_sql_user" "users" {
|
||||
name = "me"
|
||||
instance = "${google_sql_database_instance.master.name}"
|
||||
host = "me.com"
|
||||
password = "${data.google_kms_secret.sql_user_password.plaintext}"
|
||||
}
|
||||
```
|
||||
|
||||
This will result in a Cloud SQL user being created with password `my-secret-password`.
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `ciphertext` (Required) - The ciphertext to be decrypted, encoded in base64
|
||||
* `crypto_key` (Required) - The id of the CryptoKey that will be used to
|
||||
decrypt the provided ciphertext. This is represented by the format
|
||||
`{projectId}/{location}/{keyRingName}/{cryptoKeyName}`.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attribute is exported:
|
||||
|
||||
* `plaintext` - Contains the result of decrypting the provided ciphertext.
|
@ -55,6 +55,9 @@
|
||||
<li<%= sidebar_current("docs-google-datasource-iam-policy") %>>
|
||||
<a href="/docs/providers/google/d/google_iam_policy.html">google_iam_policy</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-google-kms-secret") %>>
|
||||
<a href="/docs/providers/google/d/google_kms_secret.html">google_kms_secret</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-google-datasource-signed_url") %>>
|
||||
<a href="/docs/providers/google/d/signed_url.html">google_storage_object_signed_url</a>
|
||||
</li>
|
||||
|
Loading…
Reference in New Issue
Block a user