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