diff --git a/google/resource_kms_crypto_key.go b/google/resource_kms_crypto_key.go index e2f569c319e..a66ff91c36f 100644 --- a/google/resource_kms_crypto_key.go +++ b/google/resource_kms_crypto_key.go @@ -16,6 +16,7 @@ func resourceKmsCryptoKey() *schema.Resource { return &schema.Resource{ Create: resourceKmsCryptoKeyCreate, Read: resourceKmsCryptoKeyRead, + Update: resourceKmsCryptoKeyUpdate, Delete: resourceKmsCryptoKeyDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -36,7 +37,6 @@ func resourceKmsCryptoKey() *schema.Resource { "rotation_period": &schema.Schema{ Type: schema.TypeString, Optional: true, - ForceNew: true, ValidateFunc: validateKmsCryptoKeyRotationPeriod, }, }, @@ -111,6 +111,41 @@ func resourceKmsCryptoKeyCreate(d *schema.ResourceData, meta interface{}) error return resourceKmsCryptoKeyRead(d, meta) } +func resourceKmsCryptoKeyUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + cryptoKeyId, err := parseKmsCryptoKeyId(d.Id(), config) + if err != nil { + return err + } + + key := cloudkms.CryptoKey{} + + if d.HasChange("rotation_period") && d.Get("rotation_period") != "" { + rotationPeriod := d.Get("rotation_period").(string) + nextRotation, err := kmsCryptoKeyNextRotation(time.Now(), rotationPeriod) + + if err != nil { + return fmt.Errorf("Error setting CryptoKey rotation period: %s", err.Error()) + } + + key.NextRotationTime = nextRotation + key.RotationPeriod = rotationPeriod + } + + cryptoKey, err := config.clientKms.Projects.Locations.KeyRings.CryptoKeys.Patch(cryptoKeyId.cryptoKeyId(), &key).UpdateMask("rotation_period,next_rotation_time").Do() + + if err != nil { + return fmt.Errorf("Error updating CryptoKey: %s", err.Error()) + } + + log.Printf("[DEBUG] Updated CryptoKey %s", cryptoKey.Name) + + d.SetId(cryptoKeyId.cryptoKeyId()) + + return resourceKmsCryptoKeyRead(d, meta) +} + func resourceKmsCryptoKeyRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) diff --git a/google/resource_kms_crypto_key_test.go b/google/resource_kms_crypto_key_test.go index e7090e5195c..7fdde73b1ad 100644 --- a/google/resource_kms_crypto_key_test.go +++ b/google/resource_kms_crypto_key_test.go @@ -146,6 +146,7 @@ func TestAccKmsCryptoKey_rotation(t *testing.T) { keyRingName := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) cryptoKeyName := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) rotationPeriod := "100000s" + updatedRotationPeriod := "7776000s" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -158,6 +159,20 @@ func TestAccKmsCryptoKey_rotation(t *testing.T) { testAccCheckGoogleKmsCryptoKeyHasRotationParams(rotationPeriod, "google_kms_crypto_key.crypto_key"), ), }, + resource.TestStep{ + Config: testGoogleKmsCryptoKey_rotation(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName, updatedRotationPeriod), + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleKmsCryptoKeyExists("google_kms_crypto_key.crypto_key"), + testAccCheckGoogleKmsCryptoKeyHasRotationParams(updatedRotationPeriod, "google_kms_crypto_key.crypto_key"), + ), + }, + resource.TestStep{ + Config: testGoogleKmsCryptoKey_rotationRemoved(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleKmsCryptoKeyExists("google_kms_crypto_key.crypto_key"), + testAccCheckGoogleKmsCryptoKeyHasRotationParams("", "google_kms_crypto_key.crypto_key"), + ), + }, // Use a separate TestStep rather than a CheckDestroy because we need the project to still exist. resource.TestStep{ Config: testGoogleKmsCryptoKey_removed(projectId, projectOrg, projectBillingAccount, keyRingName), @@ -237,6 +252,10 @@ func testAccCheckGoogleKmsCryptoKeyHasRotationParams(rotationPeriod, resourceNam return fmt.Errorf("Expected rotation period %s to match input %s", getCryptoKeyResponse.RotationPeriod, rotationPeriod) } + if getCryptoKeyResponse.NextRotationTime == "" { + return nil + } + _, err = time.Parse(time.RFC3339Nano, getCryptoKeyResponse.NextRotationTime) if err != nil { @@ -357,6 +376,36 @@ resource "google_kms_crypto_key" "crypto_key" { `, projectId, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName, rotationPeriod) } +func testGoogleKmsCryptoKey_rotationRemoved(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName string) string { + return fmt.Sprintf(` +resource "google_project" "acceptance" { + name = "%s" + project_id = "%s" + org_id = "%s" + billing_account = "%s" +} + +resource "google_project_services" "acceptance" { + project = "${google_project.acceptance.project_id}" + + services = [ + "cloudkms.googleapis.com", + ] +} + +resource "google_kms_key_ring" "key_ring" { + project = "${google_project_services.acceptance.project}" + name = "%s" + location = "us-central1" +} + +resource "google_kms_crypto_key" "crypto_key" { + name = "%s" + key_ring = "${google_kms_key_ring.key_ring.id}" +} + `, projectId, projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName) +} + func testGoogleKmsCryptoKey_removed(projectId, projectOrg, projectBillingAccount, keyRingName string) string { return fmt.Sprintf(` resource "google_project" "acceptance" {