@@ -739,3 +739,358 @@ resource "google_kms_crypto_key_iam_binding" "crypto_key2" {
739739}
740740` , context )
741741}
742+
743+ // Validates continuous backups defaults to being enabled with 14d retention, even if not explicitly configured.
744+ func TestAccAlloydbCluster_continuousBackup_enabledByDefault (t * testing.T ) {
745+ t .Parallel ()
746+
747+ context := map [string ]interface {}{
748+ "random_suffix" : acctest .RandString (t , 10 ),
749+ }
750+
751+ acctest .VcrTest (t , resource.TestCase {
752+ PreCheck : func () { acctest .AccTestPreCheck (t ) },
753+ ProtoV5ProviderFactories : acctest .ProtoV5ProviderFactories (t ),
754+ CheckDestroy : testAccCheckAlloydbClusterDestroyProducer (t ),
755+ Steps : []resource.TestStep {
756+ {
757+ Config : testAccAlloydbCluster_withoutContinuousBackupConfig (context ),
758+ Check : resource .ComposeTestCheckFunc (
759+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.enabled" , "true" ),
760+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.recovery_window_days" , "14" ),
761+ ),
762+ },
763+ {
764+ ResourceName : "google_alloydb_cluster.default" ,
765+ ImportState : true ,
766+ ImportStateVerify : true ,
767+ ImportStateVerifyIgnore : []string {"initial_user" , "cluster_id" , "location" },
768+ },
769+ {
770+ Config : testAccAlloydbCluster_alloydbClusterBasicExample (context ),
771+ },
772+ },
773+ })
774+ }
775+
776+ // Continuous backups defaults to being enabled with 14d retention. If the same configuration is set explicitly, terraform plan
777+ // should return no changes.
778+ func TestAccAlloydbCluster_continuousBackup_update_noChangeIfDefaultsSet (t * testing.T ) {
779+ t .Parallel ()
780+
781+ context := map [string ]interface {}{
782+ "random_suffix" : acctest .RandString (t , 10 ),
783+ "enabled" : true ,
784+ "recovery_window_days" : 14 ,
785+ }
786+
787+ acctest .VcrTest (t , resource.TestCase {
788+ PreCheck : func () { acctest .AccTestPreCheck (t ) },
789+ ProtoV5ProviderFactories : acctest .ProtoV5ProviderFactories (t ),
790+ CheckDestroy : testAccCheckAlloydbClusterDestroyProducer (t ),
791+ Steps : []resource.TestStep {
792+ {
793+ Config : testAccAlloydbCluster_withoutContinuousBackupConfig (context ),
794+ Check : resource .ComposeTestCheckFunc (
795+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.enabled" , "true" ),
796+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.recovery_window_days" , "14" ),
797+ ),
798+ },
799+ {
800+ ResourceName : "google_alloydb_cluster.default" ,
801+ ImportState : true ,
802+ ImportStateVerify : true ,
803+ ImportStateVerifyIgnore : []string {"initial_user" , "cluster_id" , "location" },
804+ },
805+ {
806+ Config : testAccAlloydbCluster_continuousBackupConfig (context ),
807+ Check : resource .ComposeTestCheckFunc (
808+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.enabled" , "true" ),
809+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.recovery_window_days" , "14" ),
810+ ),
811+ },
812+ {
813+ ResourceName : "google_alloydb_cluster.default" ,
814+ ImportState : true ,
815+ ImportStateVerify : true ,
816+ ImportStateVerifyIgnore : []string {"initial_user" , "cluster_id" , "location" },
817+ },
818+ {
819+ Config : testAccAlloydbCluster_alloydbClusterBasicExample (context ),
820+ },
821+ },
822+ })
823+ }
824+
825+ // This test ensures that if you start with a terraform configuration where continuous backups are explicitly set to the default configuration
826+ // and then remove continuous backups and call terraform plan, no changes would be found.
827+ func TestAccAlloydbCluster_continuousBackup_noChangeIfRemoved (t * testing.T ) {
828+ t .Parallel ()
829+
830+ context := map [string ]interface {}{
831+ "random_suffix" : acctest .RandString (t , 10 ),
832+ "enabled" : true ,
833+ "recovery_window_days" : 14 ,
834+ }
835+
836+ acctest .VcrTest (t , resource.TestCase {
837+ PreCheck : func () { acctest .AccTestPreCheck (t ) },
838+ ProtoV5ProviderFactories : acctest .ProtoV5ProviderFactories (t ),
839+ CheckDestroy : testAccCheckAlloydbClusterDestroyProducer (t ),
840+ Steps : []resource.TestStep {
841+ {
842+ Config : testAccAlloydbCluster_continuousBackupConfig (context ),
843+ Check : resource .ComposeTestCheckFunc (
844+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.enabled" , "true" ),
845+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.recovery_window_days" , "14" ),
846+ ),
847+ },
848+ {
849+ ResourceName : "google_alloydb_cluster.default" ,
850+ ImportState : true ,
851+ ImportStateVerify : true ,
852+ ImportStateVerifyIgnore : []string {"initial_user" , "cluster_id" , "location" },
853+ },
854+ {
855+ Config : testAccAlloydbCluster_alloydbClusterBasicExample (context ),
856+ Check : resource .ComposeTestCheckFunc (
857+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.enabled" , "true" ),
858+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.recovery_window_days" , "14" ),
859+ ),
860+ },
861+ },
862+ })
863+ }
864+
865+ // Ensures changes to the continuous backup config properly applies
866+ func TestAccAlloydbCluster_continuousBackup_update (t * testing.T ) {
867+ t .Parallel ()
868+
869+ suffix := acctest .RandString (t , 10 )
870+ context := map [string ]interface {}{
871+ "random_suffix" : suffix ,
872+ "enabled" : true ,
873+ "recovery_window_days" : 15 ,
874+ }
875+ context2 := map [string ]interface {}{
876+ "random_suffix" : suffix ,
877+ "enabled" : false ,
878+ "recovery_window_days" : 14 ,
879+ }
880+
881+ acctest .VcrTest (t , resource.TestCase {
882+ PreCheck : func () { acctest .AccTestPreCheck (t ) },
883+ ProtoV5ProviderFactories : acctest .ProtoV5ProviderFactories (t ),
884+ CheckDestroy : testAccCheckAlloydbClusterDestroyProducer (t ),
885+ Steps : []resource.TestStep {
886+ {
887+ Config : testAccAlloydbCluster_withoutContinuousBackupConfig (context ),
888+ Check : resource .ComposeTestCheckFunc (
889+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.enabled" , "true" ),
890+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.recovery_window_days" , "14" ),
891+ ),
892+ },
893+ {
894+ ResourceName : "google_alloydb_cluster.default" ,
895+ ImportState : true ,
896+ ImportStateVerify : true ,
897+ ImportStateVerifyIgnore : []string {"initial_user" , "cluster_id" , "location" },
898+ },
899+ {
900+ Config : testAccAlloydbCluster_continuousBackupConfig (context ),
901+ Check : resource .ComposeTestCheckFunc (
902+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.enabled" , "true" ),
903+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.recovery_window_days" , "15" ),
904+ ),
905+ },
906+ {
907+ ResourceName : "google_alloydb_cluster.default" ,
908+ ImportState : true ,
909+ ImportStateVerify : true ,
910+ ImportStateVerifyIgnore : []string {"initial_user" , "cluster_id" , "location" },
911+ },
912+ {
913+ Config : testAccAlloydbCluster_continuousBackupConfig (context2 ),
914+ Check : resource .ComposeTestCheckFunc (
915+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.enabled" , "false" ),
916+ resource .TestCheckResourceAttr ("google_alloydb_cluster.default" , "continuous_backup_config.0.recovery_window_days" , "14" ),
917+ ),
918+ },
919+ {
920+ ResourceName : "google_alloydb_cluster.default" ,
921+ ImportState : true ,
922+ ImportStateVerify : true ,
923+ ImportStateVerifyIgnore : []string {"initial_user" , "cluster_id" , "location" },
924+ },
925+ {
926+ Config : testAccAlloydbCluster_alloydbClusterBasicExample (context ),
927+ },
928+ },
929+ })
930+ }
931+
932+ func testAccAlloydbCluster_withoutContinuousBackupConfig (context map [string ]interface {}) string {
933+ return acctest .Nprintf (`
934+ resource "google_alloydb_cluster" "default" {
935+ cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
936+ location = "us-central1"
937+ network = "projects/${data.google_project.project.number}/global/networks/${google_compute_network.default.name}"
938+ lifecycle {
939+ prevent_destroy = true
940+ }
941+ }
942+
943+ data "google_project" "project" {
944+ }
945+
946+ resource "google_compute_network" "default" {
947+ name = "tf-test-alloydb-cluster%{random_suffix}"
948+ }
949+ ` , context )
950+ }
951+
952+ func testAccAlloydbCluster_continuousBackupConfig (context map [string ]interface {}) string {
953+ return acctest .Nprintf (`
954+ resource "google_alloydb_cluster" "default" {
955+ cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
956+ location = "us-central1"
957+ network = "projects/${data.google_project.project.number}/global/networks/${google_compute_network.default.name}"
958+
959+ continuous_backup_config {
960+ enabled = %{enabled}
961+ recovery_window_days = %{recovery_window_days}
962+ }
963+ lifecycle {
964+ prevent_destroy = true
965+ }
966+ }
967+
968+ data "google_project" "project" {
969+ }
970+
971+ resource "google_compute_network" "default" {
972+ name = "tf-test-alloydb-cluster%{random_suffix}"
973+ }
974+ ` , context )
975+ }
976+
977+ func TestAccAlloydbCluster_continuousBackup_CMEKIsUpdatable (t * testing.T ) {
978+ t .Parallel ()
979+
980+ suffix := acctest .RandString (t , 10 )
981+ kms := acctest .BootstrapKMSKeyWithPurposeInLocationAndName (t , "ENCRYPT_DECRYPT" , "us-central1" , "tf-bootstrap-alloydb-key1" )
982+ context := map [string ]interface {}{
983+ "random_suffix" : suffix ,
984+ "key_ring" : kms .KeyRing .Name ,
985+ "key_name" : kms .CryptoKey .Name ,
986+ }
987+
988+ kms2 := acctest .BootstrapKMSKeyWithPurposeInLocationAndName (t , "ENCRYPT_DECRYPT" , "us-central1" , "tf-bootstrap-alloydb-key2" )
989+ context2 := map [string ]interface {}{
990+ "random_suffix" : suffix ,
991+ "key_ring" : kms2 .KeyRing .Name ,
992+ "key_name" : kms2 .CryptoKey .Name ,
993+ }
994+
995+ acctest .VcrTest (t , resource.TestCase {
996+ PreCheck : func () { acctest .AccTestPreCheck (t ) },
997+ ProtoV5ProviderFactories : acctest .ProtoV5ProviderFactories (t ),
998+ CheckDestroy : testAccCheckAlloydbClusterDestroyProducer (t ),
999+ Steps : []resource.TestStep {
1000+ {
1001+ Config : testAccAlloydbCluster_usingCMEKInClusterAndContinuousBackup (context ),
1002+ },
1003+ {
1004+ ResourceName : "google_alloydb_cluster.default" ,
1005+ ImportState : true ,
1006+ ImportStateVerify : true ,
1007+ ImportStateVerifyIgnore : []string {"cluster_id" , "location" },
1008+ },
1009+ {
1010+ Config : testAccAlloydbCluster_usingCMEKInClusterAndContinuousBackup (context2 ),
1011+ },
1012+ {
1013+ ResourceName : "google_alloydb_cluster.default" ,
1014+ ImportState : true ,
1015+ ImportStateVerify : true ,
1016+ ImportStateVerifyIgnore : []string {"cluster_id" , "location" },
1017+ },
1018+ {
1019+ Config : testAccAlloydbCluster_continuousBackupUsingCMEKAllowDeletion (context2 ),
1020+ },
1021+ {
1022+ ResourceName : "google_alloydb_cluster.default" ,
1023+ ImportState : true ,
1024+ ImportStateVerify : true ,
1025+ ImportStateVerifyIgnore : []string {"cluster_id" , "location" },
1026+ },
1027+ },
1028+ })
1029+ }
1030+
1031+ func testAccAlloydbCluster_usingCMEKInClusterAndContinuousBackup (context map [string ]interface {}) string {
1032+ return acctest .Nprintf (`
1033+ resource "google_alloydb_cluster" "default" {
1034+ cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
1035+ location = "us-central1"
1036+ network = "projects/${data.google_project.project.number}/global/networks/${google_compute_network.default.name}"
1037+ continuous_backup_config {
1038+ enabled = true
1039+ recovery_window_days = 20
1040+ encryption_config {
1041+ kms_key_name = "%{key_name}"
1042+ }
1043+ }
1044+ lifecycle {
1045+ prevent_destroy = true
1046+ }
1047+ depends_on = [google_kms_crypto_key_iam_binding.crypto_key]
1048+ }
1049+
1050+ resource "google_compute_network" "default" {
1051+ name = "tf-test-alloydb-cluster%{random_suffix}"
1052+ }
1053+
1054+ data "google_project" "project" {}
1055+
1056+ resource "google_kms_crypto_key_iam_binding" "crypto_key" {
1057+ crypto_key_id = "%{key_name}"
1058+ role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
1059+ members = [
1060+ "serviceAccount:service-${data.google_project.project.number}@gcp-sa-alloydb.iam.gserviceaccount.com",
1061+ ]
1062+ }
1063+ ` , context )
1064+ }
1065+
1066+ func testAccAlloydbCluster_continuousBackupUsingCMEKAllowDeletion (context map [string ]interface {}) string {
1067+ return acctest .Nprintf (`
1068+ resource "google_alloydb_cluster" "default" {
1069+ cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
1070+ location = "us-central1"
1071+ network = "projects/${data.google_project.project.number}/global/networks/${google_compute_network.default.name}"
1072+ continuous_backup_config {
1073+ enabled = true
1074+ recovery_window_days = 20
1075+ encryption_config {
1076+ kms_key_name = "%{key_name}"
1077+ }
1078+ }
1079+ depends_on = [google_kms_crypto_key_iam_binding.crypto_key]
1080+ }
1081+
1082+ resource "google_compute_network" "default" {
1083+ name = "tf-test-alloydb-cluster%{random_suffix}"
1084+ }
1085+
1086+ data "google_project" "project" {}
1087+
1088+ resource "google_kms_crypto_key_iam_binding" "crypto_key" {
1089+ crypto_key_id = "%{key_name}"
1090+ role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
1091+ members = [
1092+ "serviceAccount:service-${data.google_project.project.number}@gcp-sa-alloydb.iam.gserviceaccount.com",
1093+ ]
1094+ }
1095+ ` , context )
1096+ }
0 commit comments