diff --git a/.changelog/2920.txt b/.changelog/2920.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index d7f4812647c..be64d3fd830 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -9,10 +9,10 @@ about: For when something is there, but doesn't work how it should. ### Community Note -* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request -* Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request -* If you are interested in working on this issue or have submitted a pull request, please leave a comment -* If an issue is assigned to the "modular-magician" user, it is either in the process of being autogenerated, or is planned to be autogenerated soon. If an issue is assigned to a user, that user is claiming responsibility for the issue. If an issue is assigned to "hashibot", a community member has claimed the issue already. +* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request. +* Please do not leave _+1_ or _me too_ comments, they generate extra noise for issue followers and do not help prioritize the request. +* If you are interested in working on this issue or have submitted a pull request, please leave a comment. +* If an issue is assigned to the `modular-magician` user, it is either in the process of being autogenerated, or is planned to be autogenerated soon. If an issue is assigned to a user, that user is claiming responsibility for the issue. If an issue is assigned to `hashibot`, a community member has claimed the issue already. @@ -31,12 +31,16 @@ about: For when something is there, but doesn't work how it should. ```tf -# Copy-paste your Terraform configurations here - for large Terraform configs, -# please use a service like Dropbox and share a link to the ZIP file. For -# security, you can also encrypt the files using our GPG public key: https://www.hashicorp.com/security +# Copy-paste your Terraform configurations here. +# +# For large Terraform configs, please use a service like Dropbox and share a link to the ZIP file. +# For security, you can also encrypt the files using our GPG public key: +# https://www.hashicorp.com/security +# # If reproducing the bug involves modifying the config file (e.g., apply a config, -# change a value, apply the config again, see the bug) then please include both the -# version of the config before the change, and the version of the config after the change. +# change a value, apply the config again, see the bug), then please include both: +# * the version of the config before the change, and +# * the version of the config after the change. ``` ### Debug Output diff --git a/google/bootstrap_utils_test.go b/google/bootstrap_utils_test.go index fcab7f2e1f5..f654f55e4db 100644 --- a/google/bootstrap_utils_test.go +++ b/google/bootstrap_utils_test.go @@ -6,6 +6,7 @@ import ( "log" "os" "testing" + "time" "google.golang.org/api/cloudkms/v1" "google.golang.org/api/iam/v1" @@ -230,3 +231,63 @@ func BootstrapServiceAccount(t *testing.T, project, testRunner string) string { return sa.Email } + +const SharedTestNetworkPrefix = "tf-bootstrap-net-" + +// BootstrapSharedServiceNetworkingConsumerNetwork will return a shared compute network +// for service networking test to prevent hitting limits on tenancy projects. +// +// This will either return an existing network or create one if it hasn't been created +// in the project yet. One consumer network/tenant project we don't own is created +// per producer network (i.e. network created by test), with a hard limit set. +func BootstrapSharedServiceNetworkingConsumerNetwork(t *testing.T, testId string) string { + if v := os.Getenv("TF_ACC"); v == "" { + log.Println("Acceptance tests and bootstrapping skipped unless env 'TF_ACC' set") + // If not running acceptance tests, return an empty string + return "" + } + + project := getTestProjectFromEnv() + networkName := SharedTestNetworkPrefix + testId + config := &Config{ + Credentials: getTestCredsFromEnv(), + Project: project, + Region: getTestRegionFromEnv(), + Zone: getTestZoneFromEnv(), + } + ConfigureBasePaths(config) + if err := config.LoadAndValidate(context.Background()); err != nil { + t.Errorf("Unable to bootstrap network: %s", err) + } + + log.Printf("[DEBUG] Getting shared test network %q", networkName) + _, err := config.clientCompute.Networks.Get(project, networkName).Do() + if err != nil && isGoogleApiErrorWithCode(err, 404) { + log.Printf("[DEBUG] Network %q not found, bootstrapping", networkName) + url := fmt.Sprintf("%sprojects/%s/global/networks", config.ComputeBasePath, project) + netObj := map[string]interface{}{ + "name": networkName, + "autoCreateSubnetworks": false, + } + + res, err := sendRequestWithTimeout(config, "POST", project, url, netObj, 4*time.Minute) + if err != nil { + t.Fatalf("Error bootstrapping shared test network %q: %s", networkName, err) + } + + log.Printf("[DEBUG] Waiting for network creation to finish") + err = computeOperationWaitTime(config, res, project, "Error bootstrapping shared test network", 4) + if err != nil { + t.Fatalf("Error bootstrapping shared test network %q: %s", networkName, err) + } + } + + network, err := config.clientCompute.Networks.Get(project, networkName).Do() + if err != nil { + t.Errorf("Error getting shared test network %q: %s", networkName, err) + } + if network == nil { + t.Fatalf("Error getting shared test network %q: is nil", networkName) + } + return network.Name +} diff --git a/google/data_source_google_kms_secret_ciphertext.go b/google/data_source_google_kms_secret_ciphertext.go index 1a78e450bf5..2be6daca165 100644 --- a/google/data_source_google_kms_secret_ciphertext.go +++ b/google/data_source_google_kms_secret_ciphertext.go @@ -13,7 +13,8 @@ import ( func dataSourceGoogleKmsSecretCiphertext() *schema.Resource { return &schema.Resource{ - Read: dataSourceGoogleKmsSecretCiphertextRead, + DeprecationMessage: "Use the google_kms_secret_ciphertext resource instead.", + Read: dataSourceGoogleKmsSecretCiphertextRead, Schema: map[string]*schema.Schema{ "crypto_key": { Type: schema.TypeString, diff --git a/google/data_source_google_kms_secret_ciphertext_test.go b/google/data_source_google_kms_secret_ciphertext_test.go index 16675d09066..f13409161fa 100644 --- a/google/data_source_google_kms_secret_ciphertext_test.go +++ b/google/data_source_google_kms_secret_ciphertext_test.go @@ -1,113 +1,41 @@ package google import ( - "encoding/base64" "fmt" - "log" "testing" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" - "google.golang.org/api/cloudkms/v1" ) -func TestAccKmsSecretCiphertext_basic(t *testing.T) { +func TestAccDataKmsSecretCiphertext_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)) + kms := BootstrapKMSKey(t) 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{ { - Config: testGoogleKmsCryptoKey_basic(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName), + Config: testGoogleKmsSecretCiphertext_datasource(kms.CryptoKey.Name, plaintext), Check: func(s *terraform.State) error { - cryptoKeyId, err := getCryptoKeyId(s, "google_kms_crypto_key.crypto_key") + plaintext, err := testAccDecryptSecretDataWithCryptoKey(s, kms.CryptoKey.Name, "data.google_kms_secret_ciphertext.acceptance") if err != nil { return err } - // The second test asserts that the data source created a ciphertext that can be decrypted to the correct plaintext - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testGoogleKmsSecretCiphertext_datasource(cryptoKeyId.terraformId(), plaintext), - Check: func(s *terraform.State) error { - plaintext, err := testAccDecryptSecretDataWithCryptoKey(s, cryptoKeyId, "data.google_kms_secret_ciphertext.acceptance") - - if err != nil { - return err - } - - return resource.TestCheckResourceAttr("data.google_kms_secret_ciphertext.acceptance", "plaintext", plaintext)(s) - }, - }, - }, - }) - - return nil + return resource.TestCheckResourceAttr("data.google_kms_secret_ciphertext.acceptance", "plaintext", plaintext)(s) }, }, }, }) } -func getCryptoKeyId(s *terraform.State, cryptoKeyResourceName string) (*kmsCryptoKeyId, error) { - config := testAccProvider.Meta().(*Config) - rs, ok := s.RootModule().Resources[cryptoKeyResourceName] - if !ok { - return nil, fmt.Errorf("Resource not found: %s", cryptoKeyResourceName) - } - - return parseKmsCryptoKeyId(rs.Primary.Attributes["id"], config) -} - -func testAccDecryptSecretDataWithCryptoKey(s *terraform.State, cryptoKeyId *kmsCryptoKeyId, secretCiphertextResourceName string) (string, error) { - config := testAccProvider.Meta().(*Config) - rs, ok := s.RootModule().Resources[secretCiphertextResourceName] - if !ok { - return "", fmt.Errorf("Resource not found: %s", secretCiphertextResourceName) - } - ciphertext, ok := rs.Primary.Attributes["ciphertext"] - if !ok { - return "", fmt.Errorf("Attribute 'ciphertext' not found in resource '%s'", secretCiphertextResourceName) - } - - 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) - } - - plaintextBytes, err := base64.StdEncoding.DecodeString(decryptResponse.Plaintext) - - if err != nil { - return "", err - } - - plaintext := string(plaintextBytes) - log.Printf("[INFO] Successfully decrypted ciphertext and got plaintext: %s", plaintext) - - return plaintext, nil -} - func testGoogleKmsSecretCiphertext_datasource(cryptoKeyTerraformId, plaintext string) string { return fmt.Sprintf(` data "google_kms_secret_ciphertext" "acceptance" { diff --git a/google/provider.go b/google/provider.go index 2a2bb55fd96..b95f77c44f2 100644 --- a/google/provider.go +++ b/google/provider.go @@ -477,9 +477,9 @@ func Provider() terraform.ResourceProvider { return provider } -// Generated resources: 95 +// Generated resources: 96 // Generated IAM resources: 45 -// Total generated resources: 140 +// Total generated resources: 141 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -597,6 +597,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_identity_platform_tenant": resourceIdentityPlatformTenant(), "google_kms_key_ring": resourceKMSKeyRing(), "google_kms_crypto_key": resourceKMSCryptoKey(), + "google_kms_secret_ciphertext": resourceKMSSecretCiphertext(), "google_logging_metric": resourceLoggingMetric(), "google_ml_engine_model": resourceMLEngineModel(), "google_monitoring_alert_policy": resourceMonitoringAlertPolicy(), diff --git a/google/resource_kms_secret_ciphertext.go b/google/resource_kms_secret_ciphertext.go new file mode 100644 index 00000000000..712c216fb7e --- /dev/null +++ b/google/resource_kms_secret_ciphertext.go @@ -0,0 +1,165 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "encoding/base64" + "fmt" + "log" + "reflect" + "regexp" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceKMSSecretCiphertext() *schema.Resource { + return &schema.Resource{ + Create: resourceKMSSecretCiphertextCreate, + Read: resourceKMSSecretCiphertextRead, + Delete: resourceKMSSecretCiphertextDelete, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "crypto_key": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The full name of the CryptoKey that will be used to encrypt the provided plaintext. +Format: ''projects/{{project}}/locations/{{location}}/keyRings/{{keyRing}}/cryptoKeys/{{cryptoKey}}''`, + }, + "plaintext": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The plaintext to be encrypted.`, + Sensitive: true, + }, + "ciphertext": { + Type: schema.TypeString, + Computed: true, + Description: `Contains the result of encrypting the provided plaintext, encoded in base64.`, + }, + }, + } +} + +func resourceKMSSecretCiphertextCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + plaintextProp, err := expandKMSSecretCiphertextPlaintext(d.Get("plaintext"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("plaintext"); !isEmptyValue(reflect.ValueOf(plaintextProp)) && (ok || !reflect.DeepEqual(v, plaintextProp)) { + obj["plaintext"] = plaintextProp + } + + url, err := replaceVars(d, config, "{{KMSBasePath}}{{crypto_key}}:encrypt") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new SecretCiphertext: %#v", obj) + var project string + if parts := regexp.MustCompile(`projects\/([^\/]+)\/`).FindStringSubmatch(url); parts != nil { + project = parts[1] + } + res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating SecretCiphertext: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "{{crypto_key}}/{{ciphertext}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating SecretCiphertext %q: %#v", d.Id(), res) + + // we don't set anything on read and instead do it all in create + ciphertext, ok := res["ciphertext"] + if !ok { + return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.") + } + d.Set("ciphertext", ciphertext.(string)) + + id, err = replaceVars(d, config, "{{crypto_key}}/{{ciphertext}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return resourceKMSSecretCiphertextRead(d, meta) +} + +func resourceKMSSecretCiphertextRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{KMSBasePath}}{{crypto_key}}") + if err != nil { + return err + } + + var project string + if parts := regexp.MustCompile(`projects\/([^\/]+)\/`).FindStringSubmatch(url); parts != nil { + project = parts[1] + } + res, err := sendRequest(config, "GET", project, url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("KMSSecretCiphertext %q", d.Id())) + } + + res, err = resourceKMSSecretCiphertextDecoder(d, meta, res) + if err != nil { + return err + } + + if res == nil { + // Decoding the object has resulted in it being gone. It may be marked deleted + log.Printf("[DEBUG] Removing KMSSecretCiphertext because it no longer exists.") + d.SetId("") + return nil + } + + return nil +} + +func resourceKMSSecretCiphertextDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[WARNING] KMS SecretCiphertext resources"+ + " cannot be deleted from GCP. The resource %s will be removed from Terraform"+ + " state, but will still be present on the server.", d.Id()) + d.SetId("") + + return nil +} + +func expandKMSSecretCiphertextPlaintext(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + if v == nil { + return nil, nil + } + + return base64.StdEncoding.EncodeToString([]byte(v.(string))), nil +} + +func resourceKMSSecretCiphertextDecoder(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) { + return res, nil +} diff --git a/google/resource_kms_secret_ciphertext_test.go b/google/resource_kms_secret_ciphertext_test.go new file mode 100644 index 00000000000..03400ca461f --- /dev/null +++ b/google/resource_kms_secret_ciphertext_test.go @@ -0,0 +1,82 @@ +package google + +import ( + "encoding/base64" + "fmt" + "log" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "google.golang.org/api/cloudkms/v1" +) + +func TestAccKmsSecretCiphertext_basic(t *testing.T) { + t.Parallel() + + kms := BootstrapKMSKey(t) + + plaintext := fmt.Sprintf("secret-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testGoogleKmsSecretCiphertext(kms.CryptoKey.Name, plaintext), + Check: func(s *terraform.State) error { + plaintext, err := testAccDecryptSecretDataWithCryptoKey(s, kms.CryptoKey.Name, "google_kms_secret_ciphertext.acceptance") + + if err != nil { + return err + } + + return resource.TestCheckResourceAttr("google_kms_secret_ciphertext.acceptance", "plaintext", plaintext)(s) + }, + }, + }, + }) +} + +func testAccDecryptSecretDataWithCryptoKey(s *terraform.State, cryptoKeyId string, secretCiphertextResourceName string) (string, error) { + config := testAccProvider.Meta().(*Config) + rs, ok := s.RootModule().Resources[secretCiphertextResourceName] + if !ok { + return "", fmt.Errorf("Resource not found: %s", secretCiphertextResourceName) + } + ciphertext, ok := rs.Primary.Attributes["ciphertext"] + if !ok { + return "", fmt.Errorf("Attribute 'ciphertext' not found in resource '%s'", secretCiphertextResourceName) + } + + kmsDecryptRequest := &cloudkms.DecryptRequest{ + Ciphertext: ciphertext, + } + + decryptResponse, err := config.clientKms.Projects.Locations.KeyRings.CryptoKeys.Decrypt(cryptoKeyId, kmsDecryptRequest).Do() + + if err != nil { + return "", fmt.Errorf("Error decrypting ciphertext: %s", err) + } + + plaintextBytes, err := base64.StdEncoding.DecodeString(decryptResponse.Plaintext) + + if err != nil { + return "", err + } + + plaintext := string(plaintextBytes) + log.Printf("[INFO] Successfully decrypted ciphertext and got plaintext: %s", plaintext) + + return plaintext, nil +} + +func testGoogleKmsSecretCiphertext(cryptoKeyTerraformId, plaintext string) string { + return fmt.Sprintf(` +resource "google_kms_secret_ciphertext" "acceptance" { + crypto_key = "%s" + plaintext = "%s" +} +`, cryptoKeyTerraformId, plaintext) +} diff --git a/google/resource_service_networking_connection_test.go b/google/resource_service_networking_connection_test.go index 65263055da9..4932b7f7ef2 100644 --- a/google/resource_service_networking_connection_test.go +++ b/google/resource_service_networking_connection_test.go @@ -9,19 +9,20 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/terraform" ) -func TestAccServiceNetworkingConnectionCreate(t *testing.T) { +func TestAccServiceNetworkingConnection_create(t *testing.T) { t.Parallel() + network := BootstrapSharedServiceNetworkingConsumerNetwork(t, "service-networking-connection-create") + addr := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) + service := "servicenetworking.googleapis.com" + resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testServiceNetworkingConnectionDestroy(service, network), Steps: []resource.TestStep{ { - Config: testAccServiceNetworkingConnection( - fmt.Sprintf("tf-test-%s", acctest.RandString(10)), - fmt.Sprintf("tf-test-%s", acctest.RandString(10)), - "servicenetworking.googleapis.com", - ), + Config: testAccServiceNetworkingConnection(network, addr, "servicenetworking.googleapis.com"), }, { ResourceName: "google_service_networking_connection.foobar", @@ -32,49 +33,21 @@ func TestAccServiceNetworkingConnectionCreate(t *testing.T) { }) } -// Standard checkDestroy cannot be used here because destroying the network will delete -// all the networking connections so this would return false positives. -func TestAccServiceNetworkingConnectionDestroy(t *testing.T) { +func TestAccServiceNetworkingConnection_update(t *testing.T) { t.Parallel() - network := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) - addressRange := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testAccServiceNetworkingConnection( - network, - addressRange, - "servicenetworking.googleapis.com", - ), - }, - { - Config: testAccServiceNetworkingConnectionDestroy(network, addressRange), - Check: resource.ComposeTestCheckFunc( - testServiceNetworkingConnectionDestroy("servicenetworking.googleapis.com", network, getTestProjectFromEnv()), - ), - }, - }, - }) -} - -func TestAccServiceNetworkingConnectionUpdate(t *testing.T) { - t.Parallel() + network := BootstrapSharedServiceNetworkingConsumerNetwork(t, "service-networking-connection-update") + addr1 := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) + addr2 := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) + service := "servicenetworking.googleapis.com" - network := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testServiceNetworkingConnectionDestroy(service, network), Steps: []resource.TestStep{ { - Config: testAccServiceNetworkingConnection( - network, - fmt.Sprintf("tf-test-%s", acctest.RandString(10)), - "servicenetworking.googleapis.com", - ), + Config: testAccServiceNetworkingConnection(network, addr1, "servicenetworking.googleapis.com"), }, { ResourceName: "google_service_networking_connection.foobar", @@ -82,11 +55,7 @@ func TestAccServiceNetworkingConnectionUpdate(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccServiceNetworkingConnection( - network, - fmt.Sprintf("tf-test-%s", acctest.RandString(10)), - "servicenetworking.googleapis.com", - ), + Config: testAccServiceNetworkingConnection(network, addr2, "servicenetworking.googleapis.com"), }, { ResourceName: "google_service_networking_connection.foobar", @@ -98,11 +67,11 @@ func TestAccServiceNetworkingConnectionUpdate(t *testing.T) { } -func testServiceNetworkingConnectionDestroy(parent, network, project string) resource.TestCheckFunc { +func testServiceNetworkingConnectionDestroy(parent, network string) resource.TestCheckFunc { return func(s *terraform.State) error { config := testAccProvider.Meta().(*Config) parentService := "services/" + parent - networkName := fmt.Sprintf("projects/%s/global/networks/%s", project, network) + networkName := fmt.Sprintf("projects/%s/global/networks/%s", getTestProjectFromEnv(), network) response, err := config.clientServiceNetworking.Services.Connections.List(parentService). Network(networkName).Do() @@ -122,7 +91,7 @@ func testServiceNetworkingConnectionDestroy(parent, network, project string) res func testAccServiceNetworkingConnection(networkName, addressRangeName, serviceName string) string { return fmt.Sprintf(` -resource "google_compute_network" "foobar" { +data "google_compute_network" "servicenet" { name = "%s" } @@ -131,29 +100,13 @@ resource "google_compute_global_address" "foobar" { purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 - network = google_compute_network.foobar.self_link + network = data.google_compute_network.servicenet.self_link } resource "google_service_networking_connection" "foobar" { - network = google_compute_network.foobar.self_link + network = data.google_compute_network.servicenet.self_link service = "%s" reserved_peering_ranges = [google_compute_global_address.foobar.name] } `, networkName, addressRangeName, serviceName) } - -func testAccServiceNetworkingConnectionDestroy(networkName, addressRangeName string) string { - return fmt.Sprintf(` -resource "google_compute_network" "foobar" { - name = "%s" -} - -resource "google_compute_global_address" "foobar" { - name = "%s" - purpose = "VPC_PEERING" - address_type = "INTERNAL" - prefix_length = 16 - network = google_compute_network.foobar.self_link -} -`, networkName, addressRangeName) -} diff --git a/website/docs/d/google_kms_secret_ciphertext.html.markdown b/website/docs/d/google_kms_secret_ciphertext.html.markdown index cbfc407d53e..9e06d5c1057 100644 --- a/website/docs/d/google_kms_secret_ciphertext.html.markdown +++ b/website/docs/d/google_kms_secret_ciphertext.html.markdown @@ -9,6 +9,8 @@ description: |- # google\_kms\_secret\_ciphertext +!> **Warning:** This data source is deprecated. Use the [`google_kms_secret_ciphertext`](../../r/kms_secret_ciphertext.html) **resource** instead. + This data source allows you to encrypt data with Google Cloud KMS and use the ciphertext within your resource definitions. diff --git a/website/docs/r/compute_backend_bucket_signed_url_key.html.markdown b/website/docs/r/compute_backend_bucket_signed_url_key.html.markdown index 54a5ae20dd7..0ce1c4957e5 100644 --- a/website/docs/r/compute_backend_bucket_signed_url_key.html.markdown +++ b/website/docs/r/compute_backend_bucket_signed_url_key.html.markdown @@ -94,19 +94,6 @@ This resource provides the following - `create` - Default is 4 minutes. - `delete` - Default is 4 minutes. -## Import - -BackendBucketSignedUrlKey can be imported using any of these accepted formats: - -``` -$ terraform import google_compute_backend_bucket_signed_url_key.default projects/{{project}}/global/backendBuckets/{{backend_bucket}}/{{name}} -$ terraform import google_compute_backend_bucket_signed_url_key.default {{project}}/{{backend_bucket}}/{{name}} -$ terraform import google_compute_backend_bucket_signed_url_key.default {{backend_bucket}}/{{name}} -``` - --> If you're importing a resource with beta features, make sure to include `-provider=google-beta` -as an argument so that Terraform uses the correct provider to import your resource. - ## User Project Overrides This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/compute_backend_service_signed_url_key.html.markdown b/website/docs/r/compute_backend_service_signed_url_key.html.markdown index d4946a1c70b..afd2809c04d 100644 --- a/website/docs/r/compute_backend_service_signed_url_key.html.markdown +++ b/website/docs/r/compute_backend_service_signed_url_key.html.markdown @@ -132,19 +132,6 @@ This resource provides the following - `create` - Default is 4 minutes. - `delete` - Default is 4 minutes. -## Import - -BackendServiceSignedUrlKey can be imported using any of these accepted formats: - -``` -$ terraform import google_compute_backend_service_signed_url_key.default projects/{{project}}/global/backendServices/{{backend_service}}/{{name}} -$ terraform import google_compute_backend_service_signed_url_key.default {{project}}/{{backend_service}}/{{name}} -$ terraform import google_compute_backend_service_signed_url_key.default {{backend_service}}/{{name}} -``` - --> If you're importing a resource with beta features, make sure to include `-provider=google-beta` -as an argument so that Terraform uses the correct provider to import your resource. - ## User Project Overrides This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/kms_secret_ciphertext.html.markdown b/website/docs/r/kms_secret_ciphertext.html.markdown new file mode 100644 index 00000000000..4bb0c4365da --- /dev/null +++ b/website/docs/r/kms_secret_ciphertext.html.markdown @@ -0,0 +1,126 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Cloud KMS" +layout: "google" +page_title: "Google: google_kms_secret_ciphertext" +sidebar_current: "docs-google-kms-secret-ciphertext" +description: |- + Encrypts secret data with Google Cloud KMS and provides access to the ciphertext. +--- + +# google\_kms\_secret\_ciphertext + +Encrypts secret data with Google Cloud KMS and provides access to the ciphertext. + + +~> **NOTE**: Using this resource 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. + + +To get more information about SecretCiphertext, see: + +* [API documentation](https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys/encrypt) +* How-to Guides + * [Encrypting and decrypting data with a symmetric key](https://cloud.google.com/kms/docs/encrypt-decrypt) + +## Example Usage - Kms Secret Ciphertext Basic + + +```hcl +resource "google_kms_key_ring" "keyring" { + name = "keyring-example" + location = "global" +} + +resource "google_kms_crypto_key" "cryptokey" { + name = "crypto-key-example" + key_ring = google_kms_key_ring.keyring.id + rotation_period = "100000s" + + lifecycle { + prevent_destroy = true + } +} + +resource "google_kms_secret_ciphertext" "my_password" { + crypto_key = google_kms_crypto_key.cryptokey.id + plaintext = "my-secret-password" +} + +resource "google_compute_instance" "instance" { + name = "my-instance" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-9" + } + } + + network_interface { + network = "default" + + access_config { + } + } + + metadata = { + password = google_kms_secret_ciphertext.my_password.ciphertext + } +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `plaintext` - + (Required) + The plaintext to be encrypted. + +* `crypto_key` - + (Required) + The full name of the CryptoKey that will be used to encrypt the provided plaintext. + Format: `'projects/{{project}}/locations/{{location}}/keyRings/{{keyRing}}/cryptoKeys/{{cryptoKey}}'` + + +- - - + + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + + +* `ciphertext` - + Contains the result of encrypting the provided plaintext, encoded in base64. + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/google.erb b/website/google.erb index d7c556cb5b4..ed50c8727cf 100644 --- a/website/google.erb +++ b/website/google.erb @@ -865,6 +865,9 @@ > google_kms_key_ring_iam_policy + > + google_kms_secret_ciphertext +