@@ -540,6 +540,85 @@ func TestAccKmsCryptoKeyVersion_patch(t *testing.T) {
540540 })
541541}
542542
543+ func TestAccKmsCryptoKeyVersion_externalProtectionLevelOptions (t * testing.T ) {
544+ t .Parallel ()
545+
546+ projectId := fmt .Sprintf ("tf-test-%d" , acctest .RandInt (t ))
547+ projectOrg := envvar .GetTestOrgFromEnv (t )
548+ projectBillingAccount := envvar .GetTestBillingAccountFromEnv (t )
549+ keyRingName := fmt .Sprintf ("tf-test-%s" , acctest .RandString (t , 10 ))
550+ cryptoKeyName := fmt .Sprintf ("tf-test-%s" , acctest .RandString (t , 10 ))
551+ keyUri := "data.google_secret_manager_secret_version.key_uri.secret_data"
552+ updatedKeyUri := "data.google_secret_manager_secret_version.key_uri_updated.secret_data"
553+
554+ acctest .VcrTest (t , resource.TestCase {
555+ PreCheck : func () { acctest .AccTestPreCheck (t ) },
556+ ProtoV5ProviderFactories : acctest .ProtoV5ProviderFactories (t ),
557+ Steps : []resource.TestStep {
558+ {
559+ Config : testGoogleKmsCryptoKeyVersion_externalProtectionLevelOptions (projectId , projectOrg , projectBillingAccount , keyRingName , cryptoKeyName , keyUri ),
560+ },
561+ {
562+ ResourceName : "google_kms_crypto_key_version.crypto_key_version" ,
563+ ImportState : true ,
564+ ImportStateVerify : true ,
565+ ImportStateVerifyIgnore : []string {"labels" , "terraform_labels" },
566+ },
567+ {
568+ Config : testGoogleKmsCryptoKeyVersion_externalProtectionLevelOptions (projectId , projectOrg , projectBillingAccount , keyRingName , cryptoKeyName , updatedKeyUri ),
569+ },
570+ {
571+ ResourceName : "google_kms_crypto_key_version.crypto_key_version" ,
572+ ImportState : true ,
573+ ImportStateVerify : true ,
574+ ImportStateVerifyIgnore : []string {"labels" , "terraform_labels" },
575+ },
576+ },
577+ })
578+ }
579+
580+ func TestAccKmsCryptoKeyVersion_externalProtectionLevelOptionsVpc (t * testing.T ) {
581+ // This test relies on manual steps to set up the EkmConnection used for the
582+ // CryptoKeyVersion creation, which means we can't spin up a temporary project.
583+ // We also can't use bootstrapped keys because that would defeat the purpose of
584+ // this key creation test, so we skip this test for VCR to avoid KMS resource
585+ // accumulation in the TF test project (since KMS resources can't be deleted).
586+ acctest .SkipIfVcr (t )
587+ t .Parallel ()
588+
589+ projectId := envvar .GetTestProjectFromEnv ()
590+ keyRingName := fmt .Sprintf ("tf-test-%s" , acctest .RandString (t , 10 ))
591+ cryptoKeyName := fmt .Sprintf ("tf-test-%s" , acctest .RandString (t , 10 ))
592+ ekmConnectionName := fmt .Sprintf ("tf-test-%s" , acctest .RandString (t , 10 ))
593+ keyPath := "data.google_secret_manager_secret_version.key_path.secret_data"
594+ updatedKeyPath := "data.google_secret_manager_secret_version.key_path_updated.secret_data"
595+
596+ acctest .VcrTest (t , resource.TestCase {
597+ PreCheck : func () { acctest .AccTestPreCheck (t ) },
598+ ProtoV5ProviderFactories : acctest .ProtoV5ProviderFactories (t ),
599+ Steps : []resource.TestStep {
600+ {
601+ Config : testGoogleKmsCryptoKeyVersion_externalProtectionLevelOptionsVpc (projectId , keyRingName , cryptoKeyName , ekmConnectionName , keyPath ),
602+ },
603+ {
604+ ResourceName : "google_kms_crypto_key_version.crypto_key_version" ,
605+ ImportState : true ,
606+ ImportStateVerify : true ,
607+ ImportStateVerifyIgnore : []string {"labels" , "terraform_labels" },
608+ },
609+ {
610+ Config : testGoogleKmsCryptoKeyVersion_externalProtectionLevelOptionsVpc (projectId , keyRingName , cryptoKeyName , ekmConnectionName , updatedKeyPath ),
611+ },
612+ {
613+ ResourceName : "google_kms_crypto_key_version.crypto_key_version" ,
614+ ImportState : true ,
615+ ImportStateVerify : true ,
616+ ImportStateVerifyIgnore : []string {"labels" , "terraform_labels" },
617+ },
618+ },
619+ })
620+ }
621+
543622// This test runs in its own project, otherwise the test project would start to get filled
544623// with undeletable resources
545624func testGoogleKmsCryptoKey_basic (projectId , projectOrg , projectBillingAccount , keyRingName , cryptoKeyName string ) string {
@@ -955,3 +1034,147 @@ resource "google_kms_crypto_key_version" "crypto_key_version" {
9551034}
9561035` , projectId , projectId , projectOrg , projectBillingAccount , keyRingName , cryptoKeyName , preventDestroy , state )
9571036}
1037+
1038+ func testGoogleKmsCryptoKeyVersion_externalProtectionLevelOptions (projectId , projectOrg , projectBillingAccount , keyRingName , cryptoKeyName , keyUri string ) string {
1039+ return fmt .Sprintf (`
1040+ resource "google_project" "acceptance" {
1041+ name = "%s"
1042+ project_id = "%s"
1043+ org_id = "%s"
1044+ billing_account = "%s"
1045+ }
1046+
1047+ resource "google_project_service" "acceptance" {
1048+ project = google_project.acceptance.project_id
1049+ service = "cloudkms.googleapis.com"
1050+ }
1051+
1052+ resource "google_kms_key_ring" "key_ring" {
1053+ project = google_project_service.acceptance.project
1054+ name = "%s"
1055+ location = "us-central1"
1056+ }
1057+
1058+ resource "google_kms_crypto_key" "crypto_key" {
1059+ name = "%s"
1060+ key_ring = google_kms_key_ring.key_ring.id
1061+
1062+ version_template {
1063+ algorithm = "EXTERNAL_SYMMETRIC_ENCRYPTION"
1064+ protection_level = "EXTERNAL"
1065+ }
1066+
1067+ labels = {
1068+ key = "value"
1069+ }
1070+ skip_initial_version_creation = true
1071+ }
1072+
1073+ data "google_secret_manager_secret_version" "key_uri" {
1074+ secret = "external-full-key-uri"
1075+ project = "315636579862"
1076+ }
1077+ data "google_secret_manager_secret_version" "key_uri_updated" {
1078+ secret = "external-full-key-uri-update-test"
1079+ project = "315636579862"
1080+ }
1081+
1082+ resource "google_kms_crypto_key_version" "crypto_key_version" {
1083+ crypto_key = google_kms_crypto_key.crypto_key.id
1084+ external_protection_level_options {
1085+ external_key_uri = %s
1086+ }
1087+ }
1088+ ` , projectId , projectId , projectOrg , projectBillingAccount , keyRingName , cryptoKeyName , keyUri )
1089+ }
1090+
1091+ // EkmConnection setup and creation is based off of resource_kms_ekm_connection_test.go
1092+ func testGoogleKmsCryptoKeyVersion_externalProtectionLevelOptionsVpc (projectId , keyRingName , cryptoKeyName , ekmConnectionName , keyPath string ) string {
1093+ return fmt .Sprintf (`
1094+ data "google_project" "vpc-project" {
1095+ project_id = "cloud-ekm-refekm-playground"
1096+ }
1097+ data "google_project" "project" {
1098+ project_id = "%s"
1099+ }
1100+
1101+ data "google_secret_manager_secret_version" "raw_der" {
1102+ secret = "playground-cert"
1103+ project = "315636579862"
1104+ }
1105+ data "google_secret_manager_secret_version" "hostname" {
1106+ secret = "external-uri"
1107+ project = "315636579862"
1108+ }
1109+ data "google_secret_manager_secret_version" "servicedirectoryservice" {
1110+ secret = "external-servicedirectoryservice"
1111+ project = "315636579862"
1112+ }
1113+
1114+ resource "google_project_iam_member" "add_sdviewer" {
1115+ project = data.google_project.vpc-project.number
1116+ role = "roles/servicedirectory.viewer"
1117+ member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-ekms.iam.gserviceaccount.com"
1118+ }
1119+ resource "google_project_iam_member" "add_pscAuthorizedService" {
1120+ project = data.google_project.vpc-project.number
1121+ role = "roles/servicedirectory.pscAuthorizedService"
1122+ member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-ekms.iam.gserviceaccount.com"
1123+ }
1124+
1125+ resource "google_kms_ekm_connection" "example-ekmconnection" {
1126+ name = "%s"
1127+ location = "us-central1"
1128+ key_management_mode = "MANUAL"
1129+ service_resolvers {
1130+ service_directory_service = data.google_secret_manager_secret_version.servicedirectoryservice.secret_data
1131+ hostname = data.google_secret_manager_secret_version.hostname.secret_data
1132+ server_certificates {
1133+ raw_der = data.google_secret_manager_secret_version.raw_der.secret_data
1134+ }
1135+ }
1136+ depends_on = [
1137+ google_project_iam_member.add_pscAuthorizedService,
1138+ google_project_iam_member.add_sdviewer
1139+ ]
1140+ }
1141+
1142+ resource "google_kms_key_ring" "key_ring" {
1143+ project = data.google_project.project.project_id
1144+ name = "%s"
1145+ location = "us-central1"
1146+ }
1147+
1148+ resource "google_kms_crypto_key" "crypto_key" {
1149+ name = "%s"
1150+ key_ring = google_kms_key_ring.key_ring.id
1151+
1152+ version_template {
1153+ algorithm = "EXTERNAL_SYMMETRIC_ENCRYPTION"
1154+ protection_level = "EXTERNAL_VPC"
1155+ }
1156+
1157+ labels = {
1158+ key = "value"
1159+ }
1160+ crypto_key_backend = google_kms_ekm_connection.example-ekmconnection.id
1161+ skip_initial_version_creation = true
1162+ }
1163+
1164+ data "google_secret_manager_secret_version" "key_path" {
1165+ secret = "external-keypath"
1166+ project = "315636579862"
1167+ }
1168+ data "google_secret_manager_secret_version" "key_path_updated" {
1169+ secret = "external-keypath-update-test"
1170+ project = "315636579862"
1171+ }
1172+
1173+ resource "google_kms_crypto_key_version" "crypto_key_version" {
1174+ crypto_key = google_kms_crypto_key.crypto_key.id
1175+ external_protection_level_options {
1176+ ekm_connection_key_path = %s
1177+ }
1178+ }
1179+ ` , projectId , ekmConnectionName , keyRingName , cryptoKeyName , keyPath )
1180+ }
0 commit comments