Secure a database with customer-managed encryption keys (CMEK)

This page describes how to use manually-created customer-managed encryption keys (CMEK) for Spanner.

To learn more about CMEK, see the Customer-managed encryption keys (CMEK) overview .

Create a CMEK-enabled database

  1. Create a key in Cloud Key Management Service (Cloud KMS). Spanner supports creating to following Cloud KMS types:

    The key must be in the same location as your Spanner instance. For example, if your Spanner instance configuration is in us-west1 , then your Cloud KMS key ring location must also be us-west1 .

    Not every Spanner multi-region instance configuration has a corresponding Cloud KMS key ring location. For Spanner databases in custom, dual-region, or multi-region instance configurations , you can use multiple regional (single-region) Cloud KMS keys to protect your database. For example:

    • If your Spanner database is in the multi-region instance configuration nam14 , then you can create Cloud KMS keys in us-east4 , northamerica-northeast1 , and us-east1 .
    • If your database is in a custom instance configuration that uses nam3 as the base instance configuration with an additional read-only replica in us-central2 , then you can create Cloud KMS keys in us-east4 , us-east1 , us-central1 , and us-central2 .

    Optional: To see a list of the replica locations in your Spanner instance configuration, use the gcloud spanner instances get-locations command:

      gcloud 
      
     spanner 
      
     instances 
      
     get 
     - 
     locations 
      
    < var>INSTANCE_ID 
    < / 
     var 
    > 
    

    For more information, see the following resources:

  2. Grant Spanner access to the key.

    1. In Cloud Shell, create and display the service agent, or display it if the account already exists:

       gcloud  
      beta  
      services  
      identity  
      create  
      --service = 
      spanner.googleapis.com  
       \ 
        
      --project = 
       PROJECT_ID 
       
      

      If you're prompted to install the gcloud Beta Commandscomponent, type Y . After installation, the command is automatically restarted.

      The gcloud services identity command creates or gets the service agent that Spanner can use to access the Cloud KMS key on your behalf.

      The service account ID is formatted like an email address:

       Service identity created: service-xxx@gcp-sa-spanner.iam.gserviceaccount.com 
      
    2. Grant the Cloud KMS CryptoKey Encrypter/Decrypter ( cloudkms.cryptoKeyEncrypterDecrypter ) role to the service account for each region ( --location ) in your Spanner instance configuration. To do so, run the gcloud kms keys add-iam-policybinding command:

       gcloud  
      kms  
      keys  
      add-iam-policy-binding  
       KMS_KEY 
        
       \ 
        
      --location  
       KMS_KEY_LOCATION 
        
       \ 
        
      --keyring  
       KMS_KEY_RING 
        
       \ 
        
      --project = 
       PROJECT_ID 
        
       \ 
        
      --member  
      serviceAccount: service-xxx@gcp-sa-spanner.iam.gserviceaccount.com 
        
       \ 
        
      --role  
      roles/cloudkms.cryptoKeyEncrypterDecrypter 
      

      Here's an example output:

       Updated IAM policy for key [KMS_KEY] 
      

      If you're using multiple Cloud KMS keys to protect your database, run the gcloud kms keys add-iam-policybinding command for all the your keys.

      This role ensures that the service account has permission to both encrypt and decrypt with the Cloud KMS key. For more information, see Cloud KMS permissions and roles .

  3. Create the database and specify your Cloud KMS key.

Console

Use the console to create databases in regional instance configurations.

  1. In the Google Cloud console, go to the Instancespage.

    Go to Spanner Instances

  2. Click the instance where you want to create a database.

  3. Click Create databaseand fill out the required fields.

  4. Click Show encryption options.

  5. Select Cloud KMS key.

  6. Select a key from the drop-down list.

    The list of keys is limited to the current Google Cloud project. To use a key from a different Google Cloud project, create the database using gcloud CLI instead of the Google Cloud console.

    Once the database is created, you can verify that the database is CMEK-enabled by viewing the Database overviewpage.

    Screenshot that shows the encryption type and key of a database

gcloud

To create a CMEK-enabled database in a regional, custom, or multi-region instance configuration, run the gcloud spanner databases create command:

 gcloud  
spanner  
databases  
create  
 DATABASE 
  
 \ 
  
--project = 
 SPANNER_PROJECT_ID 
  
 \ 
  
--instance = 
 INSTANCE_ID 
  
 \ 
  
--ddl = 
 "CREATE TABLE Users (Id INT64 NOT NULL, FirstName STRING(100) NOT NULL, LastName STRING(100) NOT NULL,) PRIMARY KEY (Id)" 
  
 \ 
  
--kms-project = 
 KMS_PROJECT_ID 
  
 \ 
  
--kms-location = 
 KMS_KEY_LOCATION 
  
 \ 
  
--kms-keyring = 
 KMS_KEYRING 
  
 \ 
  
--kms-keys = 
 KMS_KEY_1 
 [ 
,  
 KMS_KEY_2 
  
...  
 ] 
 

To verify that a database is CMEK-enabled, run the gcloud spanner databases describe command:

 gcloud  
spanner  
databases  
describe  
 DATABASE 
  
 \ 
  
--project = 
 SPANNER_PROJECT_ID 
  
 \ 
  
--instance = 
 INSTANCE_ID 
 

CMEK-enabled databases include a field for encryptionConfig , as shown in the following example output:

 encryptionConfig:
  kmsKeyNames:projects/my-kms-project/locations/eur5/keyRings/my-kms-key-ring/cryptoKeys/my-kms-key
  name: projects/my-spanner-project/instances/my-instance/databases/my-db
state: READY 

Client libraries

C#

To create a CMEK-enabled database in a regional instance configuration:

  using 
  
  Google.Cloud.Spanner.Admin.Database.V1 
 
 ; 
 using 
  
  Google.Cloud.Spanner.Common.V1 
 
 ; 
 using 
  
 System 
 ; 
 using 
  
 System.Threading.Tasks 
 ; 
 public 
  
 class 
  
 CreateDatabaseWithEncryptionKeyAsyncSample 
 { 
  
 public 
  
 async 
  
 Task<Database> 
  
 CreateDatabaseWithEncryptionKeyAsync 
 ( 
 string 
  
 projectId 
 , 
  
 string 
  
 instanceId 
 , 
  
 string 
  
 databaseId 
 , 
  
  CryptoKeyName 
 
  
 kmsKeyName 
 ) 
  
 { 
  
 // Create a DatabaseAdminClient instance that can be used to execute a 
  
 // CreateDatabaseRequest with custom encryption configuration options. 
  
  DatabaseAdminClient 
 
  
 databaseAdminClient 
  
 = 
  
  DatabaseAdminClient 
 
 . 
  Create 
 
 (); 
  
 // Define create table statement for table #1. 
  
 var 
  
 createSingersTable 
  
 = 
  
 @"CREATE TABLE Singers ( 
 SingerId INT64 NOT NULL, 
 FirstName STRING(1024), 
 LastName STRING(1024), 
 ComposerInfo BYTES(MAX) 
 ) PRIMARY KEY (SingerId)" 
 ; 
  
 // Define create table statement for table #2. 
  
 var 
  
 createAlbumsTable 
  
 = 
  
 @"CREATE TABLE Albums ( 
 SingerId INT64 NOT NULL, 
 AlbumId INT64 NOT NULL, 
 AlbumTitle STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE" 
 ; 
  
 // Create the CreateDatabase request with encryption configuration and execute it. 
  
 var 
  
 request 
  
 = 
  
 new 
  
  CreateDatabaseRequest 
 
  
 { 
  
 ParentAsInstanceName 
  
 = 
  
  InstanceName 
 
 . 
  FromProjectInstance 
 
 ( 
 projectId 
 , 
  
 instanceId 
 ), 
  
 CreateStatement 
  
 = 
  
 $"CREATE DATABASE `{databaseId}`" 
 , 
  
 ExtraStatements 
  
 = 
  
 { 
  
 createSingersTable 
 , 
  
 createAlbumsTable 
  
 }, 
  
 EncryptionConfig 
  
 = 
  
 new 
  
  EncryptionConfig 
 
  
 { 
  
 KmsKeyNameAsCryptoKeyName 
  
 = 
  
 kmsKeyName 
 , 
  
 }, 
  
 }; 
  
 var 
  
 operation 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
  CreateDatabaseAsync 
 
 ( 
 request 
 ); 
  
 // Wait until the operation has finished. 
  
 Console 
 . 
 WriteLine 
 ( 
 "Waiting for the operation to finish." 
 ); 
  
 var 
  
 completedResponse 
  
 = 
  
 await 
  
 operation 
 . 
 PollUntilCompletedAsync 
 (); 
  
 if 
  
 ( 
 completedResponse 
 . 
 IsFaulted 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Error while creating database: {completedResponse.Exception}" 
 ); 
  
 throw 
  
 completedResponse 
 . 
 Exception 
 ; 
  
 } 
  
 var 
  
 database 
  
 = 
  
 completedResponse 
 . 
 Result 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Database {database.Name} created with encryption key {database. EncryptionConfig 
.KmsKeyName}" 
 ); 
  
 return 
  
 database 
 ; 
  
 } 
 } 
 

To create a CMEK-enabled database in a multi-region instance configuration:

  using 
  
  Google.Cloud.Spanner.Admin.Database.V1 
 
 ; 
 using 
  
  Google.Cloud.Spanner.Common.V1 
 
 ; 
 using 
  
 System 
 ; 
 using 
  
 System.Collections.Generic 
 ; 
 using 
  
 System.Threading.Tasks 
 ; 
 public 
  
 class 
  
 CreateDatabaseWithMultiRegionEncryptionAsyncSample 
 { 
  
 public 
  
 async 
  
 Task<Database> 
  
 CreateDatabaseWithMultiRegionEncryptionAsync 
 ( 
 string 
  
 projectId 
 , 
  
 string 
  
 instanceId 
 , 
  
 string 
  
 databaseId 
 , 
  
 IEnumerable<CryptoKeyName> 
  
 kmsKeyNames 
 ) 
  
 { 
  
 // Create a DatabaseAdminClient instance that can be used to execute a 
  
 // CreateDatabaseRequest with custom encryption configuration options. 
  
  DatabaseAdminClient 
 
  
 databaseAdminClient 
  
 = 
  
  DatabaseAdminClient 
 
 . 
  Create 
 
 (); 
  
 // Define create table statement for table #1. 
  
 var 
  
 createSingersTable 
  
 = 
  
 @"CREATE TABLE Singers ( 
 SingerId INT64 NOT NULL, 
 FirstName STRING(1024), 
 LastName STRING(1024), 
 ComposerInfo BYTES(MAX) 
 ) PRIMARY KEY (SingerId)" 
 ; 
  
 // Define create table statement for table #2. 
  
 var 
  
 createAlbumsTable 
  
 = 
  
 @"CREATE TABLE Albums ( 
 SingerId INT64 NOT NULL, 
 AlbumId INT64 NOT NULL, 
 AlbumTitle STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE" 
 ; 
  
 // Create the CreateDatabase request with encryption configuration and execute it. 
  
 var 
  
 request 
  
 = 
  
 new 
  
  CreateDatabaseRequest 
 
  
 { 
  
 ParentAsInstanceName 
  
 = 
  
  InstanceName 
 
 . 
  FromProjectInstance 
 
 ( 
 projectId 
 , 
  
 instanceId 
 ), 
  
 CreateStatement 
  
 = 
  
 $"CREATE DATABASE `{databaseId}`" 
 , 
  
 ExtraStatements 
  
 = 
  
 { 
  
 createSingersTable 
 , 
  
 createAlbumsTable 
  
 }, 
  
 EncryptionConfig 
  
 = 
  
 new 
  
  EncryptionConfig 
 
  
 { 
  
 KmsKeyNamesAsCryptoKeyNames 
  
 = 
  
 { 
  
 kmsKeyNames 
  
 }, 
  
 }, 
  
 }; 
  
 var 
  
 operation 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
  CreateDatabaseAsync 
 
 ( 
 request 
 ); 
  
 // Wait until the operation has finished. 
  
 Console 
 . 
 WriteLine 
 ( 
 "Waiting for the operation to finish." 
 ); 
  
 var 
  
 completedResponse 
  
 = 
  
 await 
  
 operation 
 . 
 PollUntilCompletedAsync 
 (); 
  
 if 
  
 ( 
 completedResponse 
 . 
 IsFaulted 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Error while creating database: {completedResponse.Exception}" 
 ); 
  
 throw 
  
 completedResponse 
 . 
 Exception 
 ; 
  
 } 
  
 var 
  
 database 
  
 = 
  
 completedResponse 
 . 
 Result 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Database {database.Name} created with encryption keys {string.Join(" 
 , 
  
 ", kmsKeyNames)}" 
 ); 
  
 return 
  
 database 
 ; 
  
 } 
 } 
 

C++

To create a CMEK-enabled database in a regional instance configuration:

  void 
  
 CreateDatabaseWithEncryptionKey 
 ( 
  
 google 
 :: 
 cloud 
 :: 
 spanner_admin 
 :: 
 DatabaseAdminClient 
  
 client 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 project_id 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 instance_id 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 database_id 
 , 
  
 google 
 :: 
 cloud 
 :: 
 KmsKeyName 
  
 const 
&  
 encryption_key 
 ) 
  
 { 
  
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 Database 
  
 database 
 ( 
 project_id 
 , 
  
 instance_id 
 , 
  
 database_id 
 ); 
  
 google 
 :: 
 spanner 
 :: 
 admin 
 :: 
 database 
 :: 
 v1 
 :: 
 CreateDatabaseRequest 
  
 request 
 ; 
  
 request 
 . 
 set_parent 
 ( 
 database 
 . 
 instance 
 (). 
 FullName 
 ()); 
  
 request 
 . 
 set_create_statement 
 ( 
 "CREATE DATABASE `" 
  
 + 
  
 database 
 . 
 database_id 
 () 
  
 + 
  
 "`" 
 ); 
  
 request 
 . 
 add_extra_statements 
 ( 
 R 
 " 
 ""( 
 CREATE TABLE Singers ( 
 SingerId   INT64 NOT NULL, 
 FirstName  STRING(1024), 
 LastName   STRING(1024), 
 SingerInfo BYTES(MAX), 
 FullName   STRING(2049) 
 AS (ARRAY_TO_STRING([FirstName, LastName], " ")) STORED 
 ) PRIMARY KEY (SingerId) 
 )"" 
 " 
 ); 
  
 request 
 . 
 add_extra_statements 
 ( 
 R 
 " 
 ""( 
 CREATE TABLE Albums ( 
 SingerId     INT64 NOT NULL, 
 AlbumId      INT64 NOT NULL, 
 AlbumTitle   STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE 
 )"" 
 " 
 ); 
  
 request 
 . 
 mutable_encryption_config 
 () 
 - 
> set_kms_key_name 
 ( 
  
 encryption_key 
 . 
 FullName 
 ()); 
  
 auto 
  
 db 
  
 = 
  
 client 
 . 
 CreateDatabase 
 ( 
 request 
 ). 
 get 
 (); 
  
 if 
  
 ( 
 ! 
 db 
 ) 
  
 throw 
  
 std 
 :: 
 move 
 ( 
 db 
 ). 
 status 
 (); 
  
 std 
 :: 
 cout 
 << 
 "Database " 
 << 
 db 
 - 
> name 
 () 
 << 
 " created" 
 ; 
  
 std 
 :: 
 cout 
 << 
 " using encryption key " 
 << 
 encryption_key 
 . 
 FullName 
 (); 
  
 std 
 :: 
 cout 
 << 
 ". 
 \n 
 " 
 ; 
 } 
 

To create a CMEK-enabled database in a multi-region instance configuration:

  void 
  
 CreateDatabaseWithMRCMEK 
 ( 
  
 google 
 :: 
 cloud 
 :: 
 spanner_admin 
 :: 
 DatabaseAdminClient 
  
 client 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 project_id 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 instance_id 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 database_id 
 , 
  
 std 
 :: 
 vector<google 
 :: 
 cloud 
 :: 
 KmsKeyName 
>  
 const 
&  
 encryption_keys 
 ) 
  
 { 
  
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 Database 
  
 database 
 ( 
 project_id 
 , 
  
 instance_id 
 , 
  
 database_id 
 ); 
  
 google 
 :: 
 spanner 
 :: 
 admin 
 :: 
 database 
 :: 
 v1 
 :: 
 CreateDatabaseRequest 
  
 request 
 ; 
  
 request 
 . 
 set_parent 
 ( 
 database 
 . 
 instance 
 (). 
 FullName 
 ()); 
  
 request 
 . 
 set_create_statement 
 ( 
 "CREATE DATABASE `" 
  
 + 
  
 database 
 . 
 database_id 
 () 
  
 + 
  
 "`" 
 ); 
  
 request 
 . 
 add_extra_statements 
 ( 
 R 
 " 
 ""( 
 CREATE TABLE Singers ( 
 SingerId   INT64 NOT NULL, 
 FirstName  STRING(1024), 
 LastName   STRING(1024), 
 SingerInfo BYTES(MAX), 
 FullName   STRING(2049) 
 AS (ARRAY_TO_STRING([FirstName, LastName], " ")) STORED 
 ) PRIMARY KEY (SingerId) 
 )"" 
 " 
 ); 
  
 request 
 . 
 add_extra_statements 
 ( 
 R 
 " 
 ""( 
 CREATE TABLE Albums ( 
 SingerId     INT64 NOT NULL, 
 AlbumId      INT64 NOT NULL, 
 AlbumTitle   STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE 
 )"" 
 " 
 ); 
  
 for 
  
 ( 
 google 
 :: 
 cloud 
 :: 
 KmsKeyName 
  
 const 
&  
 encryption_key 
  
 : 
  
 encryption_keys 
 ) 
  
 { 
  
 request 
 . 
 mutable_encryption_config 
 () 
 - 
> add_kms_key_names 
 ( 
  
 encryption_key 
 . 
 FullName 
 ()); 
  
 } 
  
 auto 
  
 db 
  
 = 
  
 client 
 . 
 CreateDatabase 
 ( 
 request 
 ). 
 get 
 (); 
  
 if 
  
 ( 
 ! 
 db 
 ) 
  
 throw 
  
 std 
 :: 
 move 
 ( 
 db 
 ). 
 status 
 (); 
  
 std 
 :: 
 cout 
 << 
 "Database " 
 << 
 db 
 - 
> name 
 () 
 << 
 " created" 
 ; 
  
 PrintKmsKeys 
 ( 
 encryption_keys 
 ); 
 } 
 

Go

To create a CMEK-enabled database in a regional instance configuration:

  import 
  
 ( 
  
 "context" 
  
 "fmt" 
  
 "io" 
  
 "regexp" 
  
 database 
  
 "cloud.google.com/go/spanner/admin/database/apiv1" 
  
 adminpb 
  
 "cloud.google.com/go/spanner/admin/database/apiv1/databasepb" 
 ) 
 func 
  
 createDatabaseWithCustomerManagedEncryptionKey 
 ( 
 ctx 
  
 context 
 . 
 Context 
 , 
  
 w 
  
 io 
 . 
 Writer 
 , 
  
 db 
 , 
  
 kmsKeyName 
  
 string 
 ) 
  
 error 
  
 { 
  
 // db = `projects/<project>/instances/<instance-id>/database/<database-id>` 
  
 // kmsKeyName = `projects/<project>/locations/<location>/keyRings/<key_ring>/cryptoKeys/<kms_key_name>` 
  
 matches 
  
 := 
  
 regexp 
 . 
 MustCompile 
 ( 
 "^(.+)/databases/(.+)$" 
 ). 
 FindStringSubmatch 
 ( 
 db 
 ) 
  
 if 
  
 matches 
  
 == 
  
 nil 
  
 || 
  
 len 
 ( 
 matches 
 ) 
  
 != 
  
 3 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createDatabaseWithCustomerManagedEncryptionKey: invalid database id %q" 
 , 
  
 db 
 ) 
  
 } 
  
 instanceName 
  
 := 
  
 matches 
 [ 
 1 
 ] 
  
 databaseId 
  
 := 
  
 matches 
 [ 
 2 
 ] 
  
 adminClient 
 , 
  
 err 
  
 := 
  
 database 
 . 
 NewDatabaseAdminClient 
 ( 
 ctx 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createDatabaseWithCustomerManagedEncryptionKey.NewDatabaseAdminClient: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 defer 
  
 adminClient 
 . 
  Close 
 
 () 
  
 // Create a database with tables using a Customer Managed Encryption Key 
  
 req 
  
 := 
  
 adminpb 
 . 
 CreateDatabaseRequest 
 { 
  
 Parent 
 : 
  
 instanceName 
 , 
  
 CreateStatement 
 : 
  
 "CREATE DATABASE `" 
  
 + 
  
 databaseId 
  
 + 
  
 "`" 
 , 
  
 ExtraStatements 
 : 
  
 [] 
 string 
 { 
  
 `CREATE TABLE Singers ( 
 SingerId   INT64 NOT NULL, 
 FirstName  STRING(1024), 
 LastName   STRING(1024), 
 SingerInfo BYTES(MAX) 
 ) PRIMARY KEY (SingerId)` 
 , 
  
 `CREATE TABLE Albums ( 
 SingerId     INT64 NOT NULL, 
 AlbumId      INT64 NOT NULL, 
 AlbumTitle   STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE` 
 , 
  
 }, 
  
 EncryptionConfig 
 : 
  
& adminpb 
 . 
 EncryptionConfig 
 { 
 KmsKeyName 
 : 
  
 kmsKeyName 
 }, 
  
 } 
  
 op 
 , 
  
 err 
  
 := 
  
 adminClient 
 . 
 CreateDatabase 
 ( 
 ctx 
 , 
  
& req 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createDatabaseWithCustomerManagedEncryptionKey.CreateDatabase: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 dbObj 
 , 
  
 err 
  
 := 
  
 op 
 . 
 Wait 
 ( 
 ctx 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createDatabaseWithCustomerManagedEncryptionKey.Wait: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 fmt 
 . 
 Fprintf 
 ( 
 w 
 , 
  
 "Created database [%s] using encryption key %q\n" 
 , 
  
 dbObj 
 . 
 Name 
 , 
  
 dbObj 
 . 
 EncryptionConfig 
 . 
 KmsKeyName 
 ) 
  
 return 
  
 nil 
 } 
 

To create a CMEK-enabled database in a multi-region instance configuration:

  import 
  
 ( 
  
 "context" 
  
 "fmt" 
  
 "io" 
  
 database 
  
 "cloud.google.com/go/spanner/admin/database/apiv1" 
  
 adminpb 
  
 "cloud.google.com/go/spanner/admin/database/apiv1/databasepb" 
 ) 
 // createDatabaseWithCustomerManagedMultiRegionEncryptionKey creates a new database with tables using a Customer Managed Multi-Region Encryption Key. 
 func 
  
 createDatabaseWithCustomerManagedMultiRegionEncryptionKey 
 ( 
 ctx 
  
 context 
 . 
 Context 
 , 
  
 w 
  
 io 
 . 
 Writer 
 , 
  
 projectID 
 , 
  
 instanceID 
 , 
  
 databaseID 
  
 string 
 , 
  
 kmsKeyNames 
  
 [] 
 string 
 ) 
  
 error 
  
 { 
  
 // projectID = `my-project` 
  
 // instanceID = `my-instance` 
  
 // databaseID = `my-database` 
  
 // kmsKeyNames := []string{"projects/my-project/locations/locations/<location1>/keyRings/<keyRing>/cryptoKeys/<keyId>", 
  
 //	 "projects/my-project/locations/locations/<location2>/keyRings/<keyRing>/cryptoKeys/<keyId>", 
  
 //	 "projects/my-project/locations/locations/<location3>/keyRings/<keyRing>/cryptoKeys/<keyId>", 
  
 // } 
  
 adminClient 
 , 
  
 err 
  
 := 
  
 database 
 . 
 NewDatabaseAdminClient 
 ( 
 ctx 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createDatabaseWithCustomerManagedMultiRegionEncryptionKey.NewDatabaseAdminClient: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 defer 
  
 adminClient 
 . 
  Close 
 
 () 
  
 // Create a database with tables using a Customer Managed Multi-Region Encryption Key 
  
 req 
  
 := 
  
 adminpb 
 . 
 CreateDatabaseRequest 
 { 
  
 Parent 
 : 
  
 fmt 
 . 
 Sprintf 
 ( 
 "projects/%s/instances/%s" 
 , 
  
 projectID 
 , 
  
 instanceID 
 ), 
  
 CreateStatement 
 : 
  
 "CREATE DATABASE `" 
  
 + 
  
 databaseID 
  
 + 
  
 "`" 
 , 
  
 ExtraStatements 
 : 
  
 [] 
 string 
 { 
  
 `CREATE TABLE Singers ( 
 SingerId   INT64 NOT NULL, 
 FirstName  STRING(1024), 
 LastName   STRING(1024), 
 SingerInfo BYTES(MAX) 
 ) PRIMARY KEY (SingerId)` 
 , 
  
 `CREATE TABLE Albums ( 
 SingerId     INT64 NOT NULL, 
 AlbumId      INT64 NOT NULL, 
 AlbumTitle   STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE` 
 , 
  
 }, 
  
 EncryptionConfig 
 : 
  
& adminpb 
 . 
 EncryptionConfig 
 { 
 KmsKeyNames 
 : 
  
 kmsKeyNames 
 }, 
  
 } 
  
 op 
 , 
  
 err 
  
 := 
  
 adminClient 
 . 
 CreateDatabase 
 ( 
 ctx 
 , 
  
& req 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createDatabaseWithCustomerManagedMultiRegionEncryptionKey.CreateDatabase: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 dbObj 
 , 
  
 err 
  
 := 
  
 op 
 . 
 Wait 
 ( 
 ctx 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createDatabaseWithCustomerManagedMultiRegionEncryptionKey.Wait: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 fmt 
 . 
 Fprintf 
 ( 
 w 
 , 
  
 "Created database [%s] using multi-region encryption keys %q\n" 
 , 
  
 dbObj 
 . 
 Name 
 , 
  
 dbObj 
 . 
 EncryptionConfig 
 . 
 GetKmsKeyNames 
 ()) 
  
 return 
  
 nil 
 } 
 

Java

To create a CMEK-enabled database in a regional instance configuration:

  import 
  
 com.google.cloud.spanner. Spanner 
 
 ; 
 import 
  
 com.google.cloud.spanner. SpannerExceptionFactory 
 
 ; 
 import 
  
 com.google.cloud.spanner. SpannerOptions 
 
 ; 
 import 
  
 com.google.cloud.spanner.admin.database.v1. DatabaseAdminClient 
 
 ; 
 import 
  
 com.google.common.collect.ImmutableList 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. CreateDatabaseRequest 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. Database 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. EncryptionConfig 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. InstanceName 
 
 ; 
 import 
  
 java.util.concurrent.ExecutionException 
 ; 
 import 
  
 java.util.concurrent.TimeUnit 
 ; 
 import 
  
 java.util.concurrent.TimeoutException 
 ; 
 public 
  
 class 
 CreateDatabaseWithEncryptionKey 
  
 { 
  
 static 
  
 void 
  
 createDatabaseWithEncryptionKey 
 () 
  
 { 
  
 // TODO(developer): Replace these variables before running the sample. 
  
 String 
  
 projectId 
  
 = 
  
 "my-project" 
 ; 
  
 String 
  
 instanceId 
  
 = 
  
 "my-instance" 
 ; 
  
 String 
  
 databaseId 
  
 = 
  
 "my-database" 
 ; 
  
 String 
  
 kmsKeyName 
  
 = 
  
 "projects/" 
  
 + 
  
 projectId 
  
 + 
  
 "/locations/<location>/keyRings/<keyRing>/cryptoKeys/<keyId>" 
 ; 
  
 try 
  
 ( 
  Spanner 
 
  
 spanner 
  
 = 
  
  SpannerOptions 
 
 . 
 newBuilder 
 (). 
 setProjectId 
 ( 
 projectId 
 ). 
 build 
 (). 
 getService 
 (); 
  
  DatabaseAdminClient 
 
  
 adminClient 
  
 = 
  
 spanner 
 . 
  createDatabaseAdminClient 
 
 ()) 
  
 { 
  
 createDatabaseWithEncryptionKey 
 ( 
  
 adminClient 
 , 
  
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 , 
  
 kmsKeyName 
 ); 
  
 } 
  
 } 
  
 static 
  
 void 
  
 createDatabaseWithEncryptionKey 
 ( 
  DatabaseAdminClient 
 
  
 adminClient 
 , 
  
 String 
  
 projectId 
 , 
  
 String 
  
 instanceId 
 , 
  
 String 
  
 databaseId 
 , 
  
 String 
  
 kmsKeyName 
 ) 
  
 { 
  
  InstanceName 
 
  
 instanceName 
  
 = 
  
  InstanceName 
 
 . 
 of 
 ( 
 projectId 
 , 
  
 instanceId 
 ); 
  
  CreateDatabaseRequest 
 
  
 request 
  
 = 
  
  CreateDatabaseRequest 
 
 . 
 newBuilder 
 () 
  
 . 
 setParent 
 ( 
 instanceName 
 . 
  toString 
 
 ()) 
  
 . 
  setCreateStatement 
 
 ( 
 "CREATE DATABASE `" 
  
 + 
  
 databaseId 
  
 + 
  
 "`" 
 ) 
  
 . 
 setEncryptionConfig 
 ( 
  EncryptionConfig 
 
 . 
 newBuilder 
 (). 
 setKmsKeyName 
 ( 
 kmsKeyName 
 ). 
 build 
 ()) 
  
 . 
  addAllExtraStatements 
 
 ( 
  
 ImmutableList 
 . 
 of 
 ( 
  
 "CREATE TABLE Singers (" 
  
 + 
  
 "  SingerId   INT64 NOT NULL," 
  
 + 
  
 "  FirstName  STRING(1024)," 
  
 + 
  
 "  LastName   STRING(1024)," 
  
 + 
  
 "  SingerInfo BYTES(MAX)" 
  
 + 
  
 ") PRIMARY KEY (SingerId)" 
 , 
  
 "CREATE TABLE Albums (" 
  
 + 
  
 "  SingerId     INT64 NOT NULL," 
  
 + 
  
 "  AlbumId      INT64 NOT NULL," 
  
 + 
  
 "  AlbumTitle   STRING(MAX)" 
  
 + 
  
 ") PRIMARY KEY (SingerId, AlbumId)," 
  
 + 
  
 "  INTERLEAVE IN PARENT Singers ON DELETE CASCADE" 
  
 )) 
  
 . 
 build 
 (); 
  
 try 
  
 { 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Waiting for operation to complete..." 
 ); 
  
  Database 
 
  
 createdDatabase 
  
 = 
  
 adminClient 
 . 
  createDatabaseAsync 
 
 ( 
 request 
 ). 
 get 
 ( 
 120 
 , 
  
 TimeUnit 
 . 
 SECONDS 
 ); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Database %s created with encryption key %s%n" 
 , 
  
 createdDatabase 
 . 
  getName 
 
 (), 
  
 createdDatabase 
 . 
  getEncryptionConfig 
 
 (). 
 getKmsKeyName 
 () 
  
 ); 
  
 } 
  
 catch 
  
 ( 
 ExecutionException 
  
 e 
 ) 
  
 { 
  
 // If the operation failed during execution, expose the cause. 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  asSpannerException 
 
 ( 
 e 
 . 
 getCause 
 ()); 
  
 } 
  
 catch 
  
 ( 
 InterruptedException 
  
 e 
 ) 
  
 { 
  
 // Throw when a thread is waiting, sleeping, or otherwise occupied, 
  
 // and the thread is interrupted, either before or during the activity. 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  propagateInterrupt 
 
 ( 
 e 
 ); 
  
 } 
  
 catch 
  
 ( 
 TimeoutException 
  
 e 
 ) 
  
 { 
  
 // If the operation timed out propagates the timeout 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  propagateTimeout 
 
 ( 
 e 
 ); 
  
 } 
  
 } 
 } 
 

To create a CMEK-enabled database in a multi-region instance configuration:

  import 
  
 com.google.cloud.spanner. Spanner 
 
 ; 
 import 
  
 com.google.cloud.spanner. SpannerExceptionFactory 
 
 ; 
 import 
  
 com.google.cloud.spanner. SpannerOptions 
 
 ; 
 import 
  
 com.google.cloud.spanner.admin.database.v1. DatabaseAdminClient 
 
 ; 
 import 
  
 com.google.common.collect.ImmutableList 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. CreateDatabaseRequest 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. Database 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. EncryptionConfig 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. InstanceName 
 
 ; 
 import 
  
 java.util.concurrent.ExecutionException 
 ; 
 import 
  
 java.util.concurrent.TimeUnit 
 ; 
 import 
  
 java.util.concurrent.TimeoutException 
 ; 
 public 
  
 class 
 CreateDatabaseWithMultiRegionEncryptionKey 
  
 { 
  
 static 
  
 void 
  
 createDatabaseWithEncryptionKey 
 () 
  
 { 
  
 // TODO(developer): Replace these variables before running the sample. 
  
 String 
  
 projectId 
  
 = 
  
 "my-project" 
 ; 
  
 String 
  
 instanceId 
  
 = 
  
 "my-instance" 
 ; 
  
 String 
  
 databaseId 
  
 = 
  
 "my-database" 
 ; 
  
 String 
 [] 
  
 kmsKeyNames 
  
 = 
  
 new 
  
 String 
 [] 
  
 { 
  
 "projects/" 
  
 + 
  
 projectId 
  
 + 
  
 "/locations/<location1>/keyRings/<keyRing>/cryptoKeys/<keyId>" 
 , 
  
 "projects/" 
  
 + 
  
 projectId 
  
 + 
  
 "/locations/<location2>/keyRings/<keyRing>/cryptoKeys/<keyId>" 
 , 
  
 "projects/" 
  
 + 
  
 projectId 
  
 + 
  
 "/locations/<location3>/keyRings/<keyRing>/cryptoKeys/<keyId>" 
  
 }; 
  
 try 
  
 ( 
  Spanner 
 
  
 spanner 
  
 = 
  
  SpannerOptions 
 
 . 
 newBuilder 
 (). 
 setProjectId 
 ( 
 projectId 
 ). 
 build 
 (). 
 getService 
 (); 
  
  DatabaseAdminClient 
 
  
 adminClient 
  
 = 
  
 spanner 
 . 
  createDatabaseAdminClient 
 
 ()) 
  
 { 
  
 createDatabaseWithMultiRegionEncryptionKey 
 ( 
  
 adminClient 
 , 
  
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 , 
  
 kmsKeyNames 
 ); 
  
 } 
  
 } 
  
 static 
  
 void 
  
 createDatabaseWithMultiRegionEncryptionKey 
 ( 
  
  DatabaseAdminClient 
 
  
 adminClient 
 , 
  
 String 
  
 projectId 
 , 
  
 String 
  
 instanceId 
 , 
  
 String 
  
 databaseId 
 , 
  
 String 
 [] 
  
 kmsKeyNames 
 ) 
  
 { 
  
  InstanceName 
 
  
 instanceName 
  
 = 
  
  InstanceName 
 
 . 
 of 
 ( 
 projectId 
 , 
  
 instanceId 
 ); 
  
  CreateDatabaseRequest 
 
  
 request 
  
 = 
  
  CreateDatabaseRequest 
 
 . 
 newBuilder 
 () 
  
 . 
 setParent 
 ( 
 instanceName 
 . 
  toString 
 
 ()) 
  
 . 
  setCreateStatement 
 
 ( 
 "CREATE DATABASE `" 
  
 + 
  
 databaseId 
  
 + 
  
 "`" 
 ) 
  
 . 
 setEncryptionConfig 
 ( 
  
  EncryptionConfig 
 
 . 
 newBuilder 
 () 
  
 . 
 addAllKmsKeyNames 
 ( 
 ImmutableList 
 . 
 copyOf 
 ( 
 kmsKeyNames 
 )) 
  
 . 
 build 
 ()) 
  
 . 
  addAllExtraStatements 
 
 ( 
  
 ImmutableList 
 . 
 of 
 ( 
  
 "CREATE TABLE Singers (" 
  
 + 
  
 "  SingerId   INT64 NOT NULL," 
  
 + 
  
 "  FirstName  STRING(1024)," 
  
 + 
  
 "  LastName   STRING(1024)," 
  
 + 
  
 "  SingerInfo BYTES(MAX)" 
  
 + 
  
 ") PRIMARY KEY (SingerId)" 
 , 
  
 "CREATE TABLE Albums (" 
  
 + 
  
 "  SingerId     INT64 NOT NULL," 
  
 + 
  
 "  AlbumId      INT64 NOT NULL," 
  
 + 
  
 "  AlbumTitle   STRING(MAX)" 
  
 + 
  
 ") PRIMARY KEY (SingerId, AlbumId)," 
  
 + 
  
 "  INTERLEAVE IN PARENT Singers ON DELETE CASCADE" 
 )) 
  
 . 
 build 
 (); 
  
 try 
  
 { 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Waiting for operation to complete..." 
 ); 
  
  Database 
 
  
 createdDatabase 
  
 = 
  
 adminClient 
 . 
  createDatabaseAsync 
 
 ( 
 request 
 ). 
 get 
 ( 
 120 
 , 
  
 TimeUnit 
 . 
 SECONDS 
 ); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Database %s created with encryption keys %s%n" 
 , 
  
 createdDatabase 
 . 
  getName 
 
 (), 
  
 createdDatabase 
 . 
  getEncryptionConfig 
 
 (). 
 getKmsKeyNamesList 
 ()); 
  
 } 
  
 catch 
  
 ( 
 ExecutionException 
  
 e 
 ) 
  
 { 
  
 // If the operation failed during execution, expose the cause. 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  asSpannerException 
 
 ( 
 e 
 . 
 getCause 
 ()); 
  
 } 
  
 catch 
  
 ( 
 InterruptedException 
  
 e 
 ) 
  
 { 
  
 // Throw when a thread is waiting, sleeping, or otherwise occupied, 
  
 // and the thread is interrupted, either before or during the activity. 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  propagateInterrupt 
 
 ( 
 e 
 ); 
  
 } 
  
 catch 
  
 ( 
 TimeoutException 
  
 e 
 ) 
  
 { 
  
 // If the operation timed out propagates the timeout 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  propagateTimeout 
 
 ( 
 e 
 ); 
  
 } 
  
 } 
 } 
 

Node.js

To create a CMEK-enabled database in a regional instance configuration:

  // Imports the Google Cloud client library 
 const 
  
 { 
 Spanner 
 , 
  
 protos 
 } 
  
 = 
  
 require 
 ( 
 ' @google-cloud/spanner 
' 
 ); 
 /** 
 * TODO(developer): Uncomment the following lines before running the sample. 
 */ 
 // const projectId = 'my-project-id'; 
 // const instanceId = 'my-instance'; 
 // const databaseId = 'my-database'; 
 // const keyName = 
 //   'projects/my-project-id/my-region/keyRings/my-key-ring/cryptoKeys/my-key'; 
 // creates a client 
 const 
  
 spanner 
  
 = 
  
 new 
  
  Spanner 
 
 ({ 
  
 projectId 
 : 
  
 projectId 
 , 
 }); 
 // Gets a reference to a Cloud Spanner Database Admin Client object 
 const 
  
 databaseAdminClient 
  
 = 
  
 spanner 
 . 
  getDatabaseAdminClient 
 
 (); 
 // Creates a database 
 const 
  
 [ 
 operation 
 ] 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
 createDatabase 
 ({ 
  
 createStatement 
 : 
  
 'CREATE DATABASE `' 
  
 + 
  
 databaseId 
  
 + 
  
 '`' 
 , 
  
 parent 
 : 
  
 databaseAdminClient 
 . 
 instancePath 
 ( 
 projectId 
 , 
  
 instanceId 
 ), 
  
 encryptionConfig 
 : 
  
 ( 
 protos 
 . 
 google 
 . 
 spanner 
 . 
 admin 
 . 
 database 
 . 
 v1 
 . 
  EncryptionConfig 
 
  
 = 
  
 { 
  
 kmsKeyName 
 : 
  
 keyName 
 , 
  
 }), 
 }); 
 console 
 . 
 log 
 ( 
 `Waiting for operation on 
 ${ 
 databaseId 
 } 
 to complete...` 
 ); 
 await 
  
  operation 
 
 . 
 promise 
 (); 
 console 
 . 
 log 
 ( 
 `Created database 
 ${ 
 databaseId 
 } 
 on instance 
 ${ 
 instanceId 
 } 
 .` 
 ); 
 // Get encryption key 
 const 
  
 [ 
 metadata 
 ] 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
 getDatabase 
 ({ 
  
 name 
 : 
  
 databaseAdminClient 
 . 
 databasePath 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 ), 
 }); 
 console 
 . 
 log 
 ( 
  
 `Database encrypted with key 
 ${ 
 metadata 
 . 
 encryptionConfig 
 . 
 kmsKeyName 
 } 
 .` 
 , 
 ); 
 

To create a CMEK-enabled database in a multi-region instance configuration:

  /** 
 * TODO(developer): Uncomment the following lines before running the sample. 
 */ 
 // const projectId = 'my-project-id'; 
 // const instanceId = 'my-instance'; 
 // const databaseId = 'my-database'; 
 // const kmsKeyNames = 
 //   'projects/my-project-id/my-region/keyRings/my-key-ring/cryptoKeys/my-key1,projects/my-project-id/my-region/keyRings/my-key-ring/cryptoKeys/my-key2'; 
 // Imports the Google Cloud client library 
 const 
  
 { 
 Spanner 
 , 
  
 protos 
 } 
  
 = 
  
 require 
 ( 
 ' @google-cloud/spanner 
' 
 ); 
 // creates a client 
 const 
  
 spanner 
  
 = 
  
 new 
  
  Spanner 
 
 ({ 
  
 projectId 
 : 
  
 projectId 
 , 
 }); 
 // Gets a reference to a Cloud Spanner Database Admin Client object 
 const 
  
 databaseAdminClient 
  
 = 
  
 spanner 
 . 
  getDatabaseAdminClient 
 
 (); 
 async 
  
 function 
  
 createDatabaseWithMultipleKmsKeys 
 () 
  
 { 
  
 // Creates a database 
  
 const 
  
 [ 
 operation 
 ] 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
 createDatabase 
 ({ 
  
 createStatement 
 : 
  
 'CREATE DATABASE `' 
  
 + 
  
 databaseId 
  
 + 
  
 '`' 
 , 
  
 parent 
 : 
  
 databaseAdminClient 
 . 
 instancePath 
 ( 
 projectId 
 , 
  
 instanceId 
 ), 
  
 encryptionConfig 
 : 
  
 ( 
 protos 
 . 
 google 
 . 
 spanner 
 . 
 admin 
 . 
 database 
 . 
 v1 
 . 
  EncryptionConfig 
 
  
 = 
  
 { 
  
 kmsKeyNames 
 : 
  
 kmsKeyNames 
 . 
 split 
 ( 
 ',' 
 ), 
  
 }), 
  
 }); 
  
 console 
 . 
 log 
 ( 
 `Waiting for operation on 
 ${ 
 databaseId 
 } 
 to complete...` 
 ); 
  
 await 
  
  operation 
 
 . 
 promise 
 (); 
  
 console 
 . 
 log 
 ( 
 `Created database 
 ${ 
 databaseId 
 } 
 on instance 
 ${ 
 instanceId 
 } 
 .` 
 ); 
  
 // Get encryption key 
  
 const 
  
 [ 
 metadata 
 ] 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
 getDatabase 
 ({ 
  
 name 
 : 
  
 databaseAdminClient 
 . 
 databasePath 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 ), 
  
 }); 
  
 console 
 . 
 log 
 ( 
  
 `Database encrypted with keys 
 ${ 
 metadata 
 . 
 encryptionConfig 
 . 
 kmsKeyNames 
 } 
 .` 
 , 
  
 ); 
 } 
 createDatabaseWithMultipleKmsKeys 
 (); 
 

PHP

To create a CMEK-enabled database in a regional instance configuration:

  use Google\Cloud\Spanner\Admin\Database\V1\Client\DatabaseAdminClient; 
 use Google\Cloud\Spanner\Admin\Database\V1\CreateDatabaseRequest; 
 use Google\Cloud\Spanner\Admin\Database\V1\EncryptionConfig; 
 /** 
 * Creates an encrypted database with tables for sample data. 
 * Example: 
 * ``` 
 * create_database_with_encryption_key($projectId, $instanceId, $databaseId, $kmsKeyName); 
 * ``` 
 * 
 * @param string $projectId The Google Cloud project ID. 
 * @param string $instanceId The Spanner instance ID. 
 * @param string $databaseId The Spanner database ID. 
 * @param string $kmsKeyName The KMS key used for encryption. 
 */ 
 function create_database_with_encryption_key( 
 string $projectId, 
 string $instanceId, 
 string $databaseId, 
 string $kmsKeyName 
 ): void { 
 $databaseAdminClient = new DatabaseAdminClient(); 
 $instanceName = DatabaseAdminClient::instanceName($projectId, $instanceId); 
 $createDatabaseRequest = new CreateDatabaseRequest(); 
 $createDatabaseRequest->setParent($instanceName); 
 $createDatabaseRequest->setCreateStatement(sprintf('CREATE DATABASE `%s`', $databaseId)); 
 $createDatabaseRequest->setExtraStatements([ 
 'CREATE TABLE Singers ( 
 SingerId     INT64 NOT NULL, 
 FirstName    STRING(1024), 
 LastName     STRING(1024), 
 SingerInfo   BYTES(MAX) 
 ) PRIMARY KEY (SingerId)', 
 'CREATE TABLE Albums ( 
 SingerId     INT64 NOT NULL, 
 AlbumId      INT64 NOT NULL, 
 AlbumTitle   STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE' 
 ]); 
 if (!empty($kmsKeyName)) { 
 $encryptionConfig = new EncryptionConfig(); 
 $encryptionConfig->setKmsKeyName($kmsKeyName); 
 $createDatabaseRequest->setEncryptionConfig($encryptionConfig); 
 } 
 $operationResponse = $databaseAdminClient->createDatabase($createDatabaseRequest); 
 printf('Waiting for operation to complete...' . PHP_EOL); 
 $operationResponse->pollUntilComplete(); 
 if ($operationResponse->operationSucceeded()) { 
 $database = $operationResponse->getResult(); 
 printf( 
 'Created database %s on instance %s with encryption key %s' . PHP_EOL, 
 $databaseId, 
 $instanceId, 
 $database->getEncryptionConfig()->getKmsKeyName() 
 ); 
 } else { 
 $error = $operationResponse->getError(); 
 printf('Failed to create encrypted database: %s' . PHP_EOL, $error->getMessage()); 
 } 
 } 
 

To create a CMEK-enabled database in a multi-region instance configuration:

  use Google\Cloud\Spanner\Admin\Database\V1\Client\DatabaseAdminClient; 
 use Google\Cloud\Spanner\Admin\Database\V1\CreateDatabaseRequest; 
 use Google\Cloud\Spanner\Admin\Database\V1\EncryptionConfig; 
 /** 
 * Creates a MR CMEK database with tables for sample data. 
 * Example: 
 * ``` 
 * create_database_with_mr_cmek($projectId, $instanceId, $databaseId, $kmsKeyNames); 
 * ``` 
 * 
 * @param string $projectId The Google Cloud project ID. 
 * @param string $instanceId The Spanner instance ID. 
 * @param string $databaseId The Spanner database ID. 
 * @param string[] $kmsKeyNames The KMS keys used for encryption. 
 */ 
 function create_database_with_mr_cmek( 
 string $projectId, 
 string $instanceId, 
 string $databaseId, 
 array $kmsKeyNames 
 ): void { 
 $databaseAdminClient = new DatabaseAdminClient(); 
 $instanceName = DatabaseAdminClient::instanceName($projectId, $instanceId); 
 $createDatabaseRequest = new CreateDatabaseRequest(); 
 $createDatabaseRequest->setParent($instanceName); 
 $createDatabaseRequest->setCreateStatement(sprintf('CREATE DATABASE `%s`', $databaseId)); 
 $createDatabaseRequest->setExtraStatements([ 
 'CREATE TABLE Singers ( 
 SingerId     INT64 NOT NULL, 
 FirstName    STRING(1024), 
 LastName     STRING(1024), 
 SingerInfo   BYTES(MAX) 
 ) PRIMARY KEY (SingerId)', 
 'CREATE TABLE Albums ( 
 SingerId     INT64 NOT NULL, 
 AlbumId      INT64 NOT NULL, 
 AlbumTitle   STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE' 
 ]); 
 if (!empty($kmsKeyNames)) { 
 $encryptionConfig = new EncryptionConfig(); 
 $encryptionConfig->setKmsKeyNames($kmsKeyNames); 
 $createDatabaseRequest->setEncryptionConfig($encryptionConfig); 
 } 
 $operationResponse = $databaseAdminClient->createDatabase($createDatabaseRequest); 
 printf('Waiting for operation to complete...' . PHP_EOL); 
 $operationResponse->pollUntilComplete(); 
 if ($operationResponse->operationSucceeded()) { 
 $database = $operationResponse->getResult(); 
 printf( 
 'Created database %s on instance %s with encryption keys %s' . PHP_EOL, 
 $databaseId, 
 $instanceId, 
 print_r($database->getEncryptionConfig()->getKmsKeyNames(), true) 
 ); 
 } else { 
 $error = $operationResponse->getError(); 
 printf('Failed to create encrypted database: %s' . PHP_EOL, $error->getMessage()); 
 } 
 } 
 

Python

To create a CMEK-enabled database in a regional instance configuration:

  def 
  
 create_database_with_encryption_key 
 ( 
 instance_id 
 , 
 database_id 
 , 
 kms_key_name 
 ): 
  
 """Creates a database with tables using a Customer Managed Encryption Key (CMEK).""" 
 from 
  
 google.cloud.spanner_admin_database_v1 
  
 import 
  EncryptionConfig 
 
 from 
  
 google.cloud.spanner_admin_database_v1.types 
  
 import 
 spanner_database_admin 
 spanner_client 
 = 
 spanner 
 . 
 Client 
 () 
 database_admin_api 
 = 
 spanner_client 
 . 
 database_admin_api 
 request 
 = 
 spanner_database_admin 
 . 
  CreateDatabaseRequest 
 
 ( 
 parent 
 = 
 database_admin_api 
 . 
 instance_path 
 ( 
 spanner_client 
 . 
 project 
 , 
 instance_id 
 ), 
 create_statement 
 = 
 f 
 "CREATE DATABASE ` 
 { 
 database_id 
 } 
 `" 
 , 
 extra_statements 
 = 
 [ 
  
 """CREATE TABLE Singers ( 
 SingerId     INT64 NOT NULL, 
 FirstName    STRING(1024), 
 LastName     STRING(1024), 
 SingerInfo   BYTES(MAX) 
 ) PRIMARY KEY (SingerId)""" 
 , 
  
 """CREATE TABLE Albums ( 
 SingerId     INT64 NOT NULL, 
 AlbumId      INT64 NOT NULL, 
 AlbumTitle   STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE""" 
 , 
 ], 
 encryption_config 
 = 
 EncryptionConfig 
 ( 
 kms_key_name 
 = 
 kms_key_name 
 ), 
 ) 
 operation 
 = 
 database_admin_api 
 . 
 create_database 
 ( 
 request 
 = 
 request 
 ) 
 print 
 ( 
 "Waiting for operation to complete..." 
 ) 
 database 
 = 
 operation 
 . 
 result 
 ( 
 OPERATION_TIMEOUT_SECONDS 
 ) 
 print 
 ( 
 "Database 
 {} 
 created with encryption key 
 {} 
 " 
 . 
 format 
 ( 
 database 
 . 
 name 
 , 
 database 
 . 
 encryption_config 
 . 
 kms_key_name 
 ) 
 ) 
 

To create a CMEK-enabled database in a multi-region instance configuration:

  def 
  
 create_database_with_multiple_kms_keys 
 ( 
 instance_id 
 , 
 database_id 
 , 
 kms_key_names 
 ): 
  
 """Creates a database with tables using multiple KMS keys(CMEK).""" 
 from 
  
 google.cloud.spanner_admin_database_v1 
  
 import 
  EncryptionConfig 
 
 from 
  
 google.cloud.spanner_admin_database_v1.types 
  
 import 
 spanner_database_admin 
 spanner_client 
 = 
 spanner 
 . 
 Client 
 () 
 database_admin_api 
 = 
 spanner_client 
 . 
 database_admin_api 
 request 
 = 
 spanner_database_admin 
 . 
  CreateDatabaseRequest 
 
 ( 
 parent 
 = 
 database_admin_api 
 . 
 instance_path 
 ( 
 spanner_client 
 . 
 project 
 , 
 instance_id 
 ), 
 create_statement 
 = 
 f 
 "CREATE DATABASE ` 
 { 
 database_id 
 } 
 `" 
 , 
 extra_statements 
 = 
 [ 
  
 """CREATE TABLE Singers ( 
 SingerId     INT64 NOT NULL, 
 FirstName    STRING(1024), 
 LastName     STRING(1024), 
 SingerInfo   BYTES(MAX) 
 ) PRIMARY KEY (SingerId)""" 
 , 
  
 """CREATE TABLE Albums ( 
 SingerId     INT64 NOT NULL, 
 AlbumId      INT64 NOT NULL, 
 AlbumTitle   STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE""" 
 , 
 ], 
 encryption_config 
 = 
 EncryptionConfig 
 ( 
 kms_key_names 
 = 
 kms_key_names 
 ), 
 ) 
 operation 
 = 
 database_admin_api 
 . 
 create_database 
 ( 
 request 
 = 
 request 
 ) 
 print 
 ( 
 "Waiting for operation to complete..." 
 ) 
 database 
 = 
 operation 
 . 
 result 
 ( 
 OPERATION_TIMEOUT_SECONDS 
 ) 
 print 
 ( 
 "Database 
 {} 
 created with multiple KMS keys 
 {} 
 " 
 . 
 format 
 ( 
 database 
 . 
 name 
 , 
 database 
 . 
 encryption_config 
 . 
 kms_key_names 
 ) 
 ) 
 

Ruby

To create a CMEK-enabled database in a regional instance configuration:

  # project_id  = "Your Google Cloud project ID" 
 # instance_id = "Your Spanner instance ID" 
 # database_id = "Your Spanner database ID" 
 # kms_key_name = "Database eencryption KMS key" 
 require 
  
 "google/cloud/spanner" 
 require 
  
 "google/cloud/spanner/admin/database" 
 database_admin_client 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Spanner 
 :: 
 Admin 
 :: 
 Database 
 . 
 database_admin 
 instance_path 
  
 = 
  
 database_admin_client 
 . 
 instance_path 
  
 project 
 : 
  
 project_id 
 , 
  
 instance 
 : 
  
 instance_id 
 db_path 
  
 = 
  
 database_admin_client 
 . 
 database_path 
  
 project 
 : 
  
 project_id 
 , 
  
 instance 
 : 
  
 instance_id 
 , 
  
 database 
 : 
  
 database_id 
 job 
  
 = 
  
 database_admin_client 
 . 
 create_database 
  
 parent 
 : 
  
 instance_path 
 , 
  
 create_statement 
 : 
  
 "CREATE DATABASE ` 
 #{ 
 database_id 
 } 
 `" 
 , 
  
 extra_statements 
 : 
  
 [ 
  
 "CREATE TABLE Singers ( 
 SingerId     INT64 NOT NULL, 
 FirstName    STRING(1024), 
 LastName     STRING(1024), 
 SingerInfo   BYTES(MAX) 
 ) PRIMARY KEY (SingerId)" 
 , 
  
 "CREATE TABLE Albums ( 
 SingerId     INT64 NOT NULL, 
 AlbumId      INT64 NOT NULL, 
 AlbumTitle   STRING(MAX) 
 ) PRIMARY KEY (SingerId, AlbumId), 
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE" 
  
 ] 
 , 
  
 encryption_config 
 : 
  
 { 
  
 kms_key_name 
 : 
  
 kms_key_name 
  
 } 
 puts 
  
 "Waiting for create database operation to complete" 
 job 
 . 
 wait_until_done! 
 database 
  
 = 
  
 database_admin_client 
 . 
 get_database 
  
 name 
 : 
  
 db_path 
 puts 
  
 "Database 
 #{ 
 database_id 
 } 
 created with encryption key 
 #{ 
 database 
 . 
 encryption_config 
 . 
 kms_key_name 
 } 
 " 
 

To create a CMEK-enabled database in a multi-region instance configuration:

  # project_id  = "Your Google Cloud project ID" 
 # instance_id = "Your Spanner instance ID" 
 # database_id = "Your Spanner database ID" 
 # kms_key_names = ["key1", "key2", "key3"] 
 require 
  
 "google/cloud/spanner" 
 require 
  
 "google/cloud/spanner/admin/database" 
 database_admin_client 
  
 = 
  
 Google 
 :: 
 Cloud 
 :: 
 Spanner 
 :: 
 Admin 
 :: 
 Database 
 . 
 database_admin 
 instance_path 
  
 = 
  
 database_admin_client 
 . 
 instance_path 
 ( 
  
 project 
 : 
  
 project_id 
 , 
  
 instance 
 : 
  
 instance_id 
 ) 
 encryption_config 
  
 = 
  
 { 
  
 kms_key_names 
 : 
  
 kms_key_names 
 } 
 db_path 
  
 = 
  
 database_admin_client 
 . 
 database_path 
 ( 
  
 project 
 : 
  
 project_id 
 , 
  
 instance 
 : 
  
 instance_id 
 , 
  
 database 
 : 
  
 database_id 
 ) 
 job 
  
 = 
  
 database_admin_client 
 . 
 create_database 
 ( 
  
 parent 
 : 
  
 instance_path 
 , 
  
 create_statement 
 : 
  
 "CREATE DATABASE ` 
 #{ 
 database_id 
 } 
 `" 
 , 
  
 extra_statements 
 : 
  
 [ 
  
<< ~ 
 STATEMENT 
 , 
  
 CREATE 
  
 TABLE 
  
 Singers 
  
 ( 
  
 SingerId 
  
 INT64 
  
 NOT 
  
 NULL 
 , 
  
 FirstName 
  
 STRING 
 ( 
 1024 
 ), 
  
 LastName 
  
 STRING 
 ( 
 1024 
 ), 
  
 SingerInfo 
  
 BYTES 
 ( 
 MAX 
 ) 
  
 ) 
  
 PRIMARY 
  
 KEY 
  
 ( 
 SingerId 
 ) 
  
 STATEMENT 
  
<< ~ 
 STATEMENT 
  
 CREATE 
  
 TABLE 
  
 Albums 
  
 ( 
  
 SingerId 
  
 INT64 
  
 NOT 
  
 NULL 
 , 
  
 AlbumId 
  
 INT64 
  
 NOT 
  
 NULL 
 , 
  
 AlbumTitle 
  
 STRING 
 ( 
 MAX 
 ) 
  
 ) 
  
 PRIMARY 
  
 KEY 
  
 ( 
 SingerId 
 , 
  
 AlbumId 
 ), 
  
 INTERLEAVE 
  
 IN 
  
 PARENT 
  
 Singers 
  
 ON 
  
 DELETE 
  
 CASCADE 
  
 STATEMENT 
  
 ] 
 , 
  
 encryption_config 
 : 
  
 encryption_config 
 ) 
 puts 
  
 "Waiting for create database operation to complete" 
 job 
 . 
 wait_until_done! 
 database 
  
 = 
  
 database_admin_client 
 . 
 get_database 
  
 name 
 : 
  
 db_path 
 puts 
  
 "Database 
 #{ 
 database_id 
 } 
 created with encryption key " 
  
 \ 
  
 " 
 #{ 
 database 
 . 
 encryption_config 
 . 
 kms_key_names 
 } 
 " 
 

View the key versions in use

The database's encryption_info field shows information about key versions.

When a database's key version changes, the change isn't immediately propagated to encryption_info . There might be a delay before the change is reflected in this field.

Console

  1. In the Google Cloud console, go to the Instancespage.

    Go to Instances

  2. Click the instance containing the database you want to view.

  3. Click the database.

    Encryption information is displayed on the Database detailspage.

    Screenshot of the encryption information that is displayed on the Database details page.

gcloud

You can get a database's encryption_info by running the gcloud spanner databases describe or gcloud spanner databases list command. For example:

 gcloud  
spanner  
databases  
describe  
 DATABASE 
  
 \ 
  
--project = 
 SPANNER_PROJECT_ID 
  
 \ 
  
--instance = 
 INSTANCE_ID 
 

Here's an example output:

 name: projects/my-project/instances/test-instance/databases/example-db
encryptionInfo:
- encryptionType: CUSTOMER_MANAGED_ENCRYPTION
  kmsKeyVersion: projects/my-kms-project/locations/my-kms-key1-location/keyRings/my-kms-key-ring1/cryptoKeys/my-kms-key1/cryptoKeyVersions/1
- encryptionType: CUSTOMER_MANAGED_ENCRYPTION
  kmsKeyVersion: projects/my-kms-project/locations/my-kms-key2-location/keyRings/my-kms-key-ring2/cryptoKeys/my-kms-key2/cryptoKeyVersions/1 

Disable the key

  1. Disable the key version(s) that are in use by following these instructions for each key version.

  2. Wait for the change to take effect. Disabling a key can take up to three hours to propagate .

  3. To confirm that the database is no longer accessible, execute a query in the CMEK-disabled database:

     gcloud  
    spanner  
    databases  
    execute-sql  
     DATABASE 
      
     \ 
      
    --project = 
     SPANNER_PROJECT_ID 
      
     \ 
      
    --instance = 
     INSTANCE_ID 
      
     \ 
      
    --sql = 
     'SELECT * FROM Users' 
     
    

    The following error message appears: KMS key required by the Spanner resource is not accessible.

Enable the key

  1. Enable the key versions that are in use by the database by following these instructions for each key version.

  2. Wait for the change to take effect. Enabling a key can take up to three hours to propagate.

  3. To confirm that the database is no longer accessible, execute a query in the CMEK-enabled database:

     gcloud  
    spanner  
    databases  
    execute-sql  
     DATABASE 
      
     \ 
      
    --project = 
     SPANNER_PROJECT_ID 
      
     \ 
      
    --instance = 
     INSTANCE_ID 
      
     \ 
      
    --sql = 
     'SELECT * FROM Users' 
     
    

    If the change has taken effect, the command executes successfully.

Back up a database

You can use Spanner backups to create backups of your databases. By default, Spanner backups created from a database use the same encryption configuration as the database itself. You can optionally specify a different encryption configuration for a backup.

Console

Use the console to create backups in regional instance configurations.

  1. In the Google Cloud console, go to the Instancespage.

    Go to Spanner Instances

  2. Click the instance name that contains the database that you want to back up.

  3. Click the database.

  4. In the navigation pane, click Backup/Restore.

  5. In the Backupstab, click Create backup.

  6. Enter a backup name and select an expiration date.

  7. Optional: Click Show encryption options.

    a. If you want to use a different encryption configuration for your backup, click the slider next to Use existing encryption.

    a. Select Cloud KMS key.

    a. Select a key from the drop-down list.

    The list of keys is limited to the current Google Cloud project. To use a key from a different Google Cloud project, create the database using gcloud CLI instead of the Google Cloud console.

  8. Click Create.

The Backupstable displays encryption information for each backup.

Screenshot of the Backups table showing the encryption information for each backup

gcloud

To create a CMEK-enabled backup in a regional, custom, or multi-region instance configuration, run the gcloud spanner backups create command:

 gcloud  
spanner  
backups  
create  
 BACKUP 
  
 \ 
  
--project = 
 SPANNER_PROJECT_ID 
  
 \ 
  
--instance = 
 INSTANCE_ID 
  
 \ 
  
--database = 
 DATABASE 
  
 \ 
  
--retention-period = 
 RETENTION_PERIOD 
  
 \ 
  
--encryption-type = 
customer_managed_encryption  
 \ 
  
--kms-project = 
 KMS_PROJECT_ID 
  
 \ 
  
--kms-location = 
 KMS_KEY_LOCATION 
  
 \ 
  
--kms-keyring = 
 KMS_KEY_RING 
  
 \ 
  
--kms-keys = 
 KMS_KEY_1 
 [ 
,  
 KMS_KEY_2 
  
...  
 ] 
  
--async 

To verify that the backup created is CMEK encrypted:

 gcloud  
spanner  
backups  
describe  
 BACKUP 
  
 \ 
  
--project = 
 SPANNER_PROJECT_ID 
  
 \ 
  
--instance = 
 INSTANCE_ID 
 

Client libraries

C#

To create a CMEK-enabled backup in a regional instance configuration:

  using 
  
  Google.Cloud.Spanner.Admin.Database.V1 
 
 ; 
 using 
  
  Google.Cloud.Spanner.Common.V1 
 
 ; 
 using 
  
  Google.Protobuf.WellKnownTypes 
 
 ; 
 using 
  
 System 
 ; 
 using 
  
 System.Threading.Tasks 
 ; 
 public 
  
 class 
  
 CreateBackupWithEncryptionKeyAsyncSample 
 { 
  
 public 
  
 async 
  
 Task<Backup> 
  
 CreateBackupWithEncryptionKeyAsync 
 ( 
 string 
  
 projectId 
 , 
  
 string 
  
 instanceId 
 , 
  
 string 
  
 databaseId 
 , 
  
 string 
  
 backupId 
 , 
  
  CryptoKeyName 
 
  
 kmsKeyName 
 ) 
  
 { 
  
 // Create a DatabaseAdminClient instance. 
  
  DatabaseAdminClient 
 
  
 databaseAdminClient 
  
 = 
  
  DatabaseAdminClient 
 
 . 
  Create 
 
 (); 
  
 // Create the CreateBackupRequest with encryption configuration. 
  
  CreateBackupRequest 
 
  
 request 
  
 = 
  
 new 
  
  CreateBackupRequest 
 
  
 { 
  
 ParentAsInstanceName 
  
 = 
  
  InstanceName 
 
 . 
  FromProjectInstance 
 
 ( 
 projectId 
 , 
  
 instanceId 
 ), 
  
 BackupId 
  
 = 
  
 backupId 
 , 
  
 Backup 
  
 = 
  
 new 
  
  Backup 
 
  
 { 
  
 DatabaseAsDatabaseName 
  
 = 
  
  DatabaseName 
 
 . 
  FromProjectInstanceDatabase 
 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 ), 
  
 ExpireTime 
  
 = 
  
 DateTime 
 . 
 UtcNow 
 . 
 AddDays 
 ( 
 14 
 ). 
  ToTimestamp 
 
 (), 
  
 }, 
  
 EncryptionConfig 
  
 = 
  
 new 
  
  CreateBackupEncryptionConfig 
 
  
 { 
  
 EncryptionType 
  
 = 
  
  CreateBackupEncryptionConfig 
 
 . 
  Types 
 
 . 
  EncryptionType 
 
 . 
  CustomerManagedEncryption 
 
 , 
  
 KmsKeyNameAsCryptoKeyName 
  
 = 
  
 kmsKeyName 
 , 
  
 }, 
  
 }; 
  
 // Execute the CreateBackup request. 
  
 var 
  
 operation 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
  CreateBackupAsync 
 
 ( 
 request 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 "Waiting for the operation to finish." 
 ); 
  
 // Poll until the returned long-running operation is complete. 
  
 var 
  
 completedResponse 
  
 = 
  
 await 
  
 operation 
 . 
 PollUntilCompletedAsync 
 (); 
  
 if 
  
 ( 
 completedResponse 
 . 
 IsFaulted 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Error while creating backup: {completedResponse.Exception}" 
 ); 
  
 throw 
  
 completedResponse 
 . 
 Exception 
 ; 
  
 } 
  
 var 
  
 backup 
  
 = 
  
 completedResponse 
 . 
 Result 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Backup {backup.Name} of size {backup. SizeBytes 
} bytes " 
  
 + 
  
 $"was created at {backup.CreateTime} " 
  
 + 
  
 $"using encryption key {kmsKeyName}" 
 ); 
  
 return 
  
 backup 
 ; 
  
 } 
 } 
 

To create a CMEK-enabled backup in a multi-region instance configuration:

  using 
  
  Google.Cloud.Spanner.Admin.Database.V1 
 
 ; 
 using 
  
  Google.Cloud.Spanner.Common.V1 
 
 ; 
 using 
  
  Google.Protobuf.WellKnownTypes 
 
 ; 
 using 
  
 System 
 ; 
 using 
  
 System.Collections.Generic 
 ; 
 using 
  
 System.Threading.Tasks 
 ; 
 public 
  
 class 
  
 CreateBackupWithMultiRegionEncryptionAsyncSample 
 { 
  
 public 
  
 async 
  
 Task<Backup> 
  
 CreateBackupWithMultiRegionEncryptionAsync 
 ( 
 string 
  
 projectId 
 , 
  
 string 
  
 instanceId 
 , 
  
 string 
  
 databaseId 
 , 
  
 string 
  
 backupId 
 , 
  
 IEnumerable<CryptoKeyName> 
  
 kmsKeyNames 
 ) 
  
 { 
  
 // Create a DatabaseAdminClient instance. 
  
  DatabaseAdminClient 
 
  
 databaseAdminClient 
  
 = 
  
  DatabaseAdminClient 
 
 . 
  Create 
 
 (); 
  
 // Create the CreateBackupRequest with encryption configuration. 
  
  CreateBackupRequest 
 
  
 request 
  
 = 
  
 new 
  
  CreateBackupRequest 
 
  
 { 
  
 ParentAsInstanceName 
  
 = 
  
  InstanceName 
 
 . 
  FromProjectInstance 
 
 ( 
 projectId 
 , 
  
 instanceId 
 ), 
  
 BackupId 
  
 = 
  
 backupId 
 , 
  
 Backup 
  
 = 
  
 new 
  
  Backup 
 
  
 { 
  
 DatabaseAsDatabaseName 
  
 = 
  
  DatabaseName 
 
 . 
  FromProjectInstanceDatabase 
 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 ), 
  
 ExpireTime 
  
 = 
  
 DateTime 
 . 
 UtcNow 
 . 
 AddDays 
 ( 
 14 
 ). 
  ToTimestamp 
 
 (), 
  
 }, 
  
 EncryptionConfig 
  
 = 
  
 new 
  
  CreateBackupEncryptionConfig 
 
  
 { 
  
 EncryptionType 
  
 = 
  
  CreateBackupEncryptionConfig 
 
 . 
  Types 
 
 . 
  EncryptionType 
 
 . 
  CustomerManagedEncryption 
 
 , 
  
 KmsKeyNamesAsCryptoKeyNames 
  
 = 
  
 { 
  
 kmsKeyNames 
  
 }, 
  
 }, 
  
 }; 
  
 // Execute the CreateBackup request. 
  
 var 
  
 operation 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
  CreateBackupAsync 
 
 ( 
 request 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 "Waiting for the operation to finish." 
 ); 
  
 // Poll until the returned long-running operation is complete. 
  
 var 
  
 completedResponse 
  
 = 
  
 await 
  
 operation 
 . 
 PollUntilCompletedAsync 
 (); 
  
 if 
  
 ( 
 completedResponse 
 . 
 IsFaulted 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Error while creating backup: {completedResponse.Exception}" 
 ); 
  
 throw 
  
 completedResponse 
 . 
 Exception 
 ; 
  
 } 
  
 var 
  
 backup 
  
 = 
  
 completedResponse 
 . 
 Result 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Backup {backup.Name} of size {backup. SizeBytes 
} bytes was created with encryption keys {string.Join(" 
 , 
  
 ", kmsKeyNames)} at {backup.CreateTime}" 
 ); 
  
 return 
  
 backup 
 ; 
  
 } 
 } 
 

C++

To create a CMEK-enabled backup in a regional instance configuration:

  void 
  
 CreateBackupWithEncryptionKey 
 ( 
  
 google 
 :: 
 cloud 
 :: 
 spanner_admin 
 :: 
 DatabaseAdminClient 
  
 client 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 project_id 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 instance_id 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 database_id 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 backup_id 
 , 
  
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 Timestamp 
  
 expire_time 
 , 
  
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 Timestamp 
  
 version_time 
 , 
  
 google 
 :: 
 cloud 
 :: 
 KmsKeyName 
  
 const 
&  
 encryption_key 
 ) 
  
 { 
  
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 Database 
  
 database 
 ( 
 project_id 
 , 
  
 instance_id 
 , 
  
 database_id 
 ); 
  
 google 
 :: 
 spanner 
 :: 
 admin 
 :: 
 database 
 :: 
 v1 
 :: 
 CreateBackupRequest 
  
 request 
 ; 
  
 request 
 . 
 set_parent 
 ( 
 database 
 . 
 instance 
 (). 
 FullName 
 ()); 
  
 request 
 . 
 set_backup_id 
 ( 
 backup_id 
 ); 
  
 request 
 . 
 mutable_backup 
 () 
 - 
> set_database 
 ( 
 database 
 . 
 FullName 
 ()); 
  
 * 
 request 
 . 
 mutable_backup 
 () 
 - 
> mutable_expire_time 
 () 
  
 = 
  
 expire_time 
 . 
 get<google 
 :: 
 protobuf 
 :: 
 Timestamp 
> (). 
 value 
 (); 
  
 * 
 request 
 . 
 mutable_backup 
 () 
 - 
> mutable_version_time 
 () 
  
 = 
  
 version_time 
 . 
 get<google 
 :: 
 protobuf 
 :: 
 Timestamp 
> (). 
 value 
 (); 
  
 request 
 . 
 mutable_encryption_config 
 () 
 - 
> set_encryption_type 
 ( 
  
 google 
 :: 
 spanner 
 :: 
 admin 
 :: 
 database 
 :: 
 v1 
 :: 
 CreateBackupEncryptionConfig 
 :: 
  
 CUSTOMER_MANAGED_ENCRYPTION 
 ); 
  
 request 
 . 
 mutable_encryption_config 
 () 
 - 
> set_kms_key_name 
 ( 
  
 encryption_key 
 . 
 FullName 
 ()); 
  
 auto 
  
 backup 
  
 = 
  
 client 
 . 
 CreateBackup 
 ( 
 request 
 ). 
 get 
 (); 
  
 if 
  
 ( 
 ! 
 backup 
 ) 
  
 throw 
  
 std 
 :: 
 move 
 ( 
 backup 
 ). 
 status 
 (); 
  
 std 
 :: 
 cout 
 << 
 "Backup " 
 << 
 backup 
 - 
> name 
 () 
 << 
 " of " 
 << 
 backup 
 - 
> database 
 () 
 << 
 " of size " 
 << 
 backup 
 - 
> size_bytes 
 () 
 << 
 " bytes as of " 
 << 
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 MakeTimestamp 
 ( 
 backup 
 - 
> version_time 
 ()). 
 value 
 () 
 << 
 " was created at " 
 << 
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 MakeTimestamp 
 ( 
 backup 
 - 
> create_time 
 ()). 
 value 
 () 
 << 
 " using encryption key " 
 << 
 encryption_key 
 . 
 FullName 
 () 
 << 
 ". 
 \n 
 " 
 ; 
 } 
 

To create a CMEK-enabled backup in a multi-region instance configuration:

  void 
  
 CreateBackupWithMRCMEK 
 ( 
  
 google 
 :: 
 cloud 
 :: 
 spanner_admin 
 :: 
 DatabaseAdminClient 
  
 client 
 , 
  
 BackupIdentifier 
  
 dst 
 , 
  
 std 
 :: 
 string 
  
 const 
&  
 database_id 
 , 
  
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 Timestamp 
  
 expire_time 
 , 
  
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 Timestamp 
  
 version_time 
 , 
  
 std 
 :: 
 vector<google 
 :: 
 cloud 
 :: 
 KmsKeyName 
>  
 const 
&  
 encryption_keys 
 ) 
  
 { 
  
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 Database 
  
 database 
 ( 
 dst 
 . 
 project_id 
 , 
  
 dst 
 . 
 instance_id 
 , 
  
 database_id 
 ); 
  
 google 
 :: 
 spanner 
 :: 
 admin 
 :: 
 database 
 :: 
 v1 
 :: 
 CreateBackupRequest 
  
 request 
 ; 
  
 request 
 . 
 set_parent 
 ( 
 database 
 . 
 instance 
 (). 
 FullName 
 ()); 
  
 request 
 . 
 set_backup_id 
 ( 
 dst 
 . 
 backup_id 
 ); 
  
 request 
 . 
 mutable_backup 
 () 
 - 
> set_database 
 ( 
 database 
 . 
 FullName 
 ()); 
  
 * 
 request 
 . 
 mutable_backup 
 () 
 - 
> mutable_expire_time 
 () 
  
 = 
  
 expire_time 
 . 
 get<google 
 :: 
 protobuf 
 :: 
 Timestamp 
> (). 
 value 
 (); 
  
 * 
 request 
 . 
 mutable_backup 
 () 
 - 
> mutable_version_time 
 () 
  
 = 
  
 version_time 
 . 
 get<google 
 :: 
 protobuf 
 :: 
 Timestamp 
> (). 
 value 
 (); 
  
 request 
 . 
 mutable_encryption_config 
 () 
 - 
> set_encryption_type 
 ( 
  
 google 
 :: 
 spanner 
 :: 
 admin 
 :: 
 database 
 :: 
 v1 
 :: 
 CreateBackupEncryptionConfig 
 :: 
  
 CUSTOMER_MANAGED_ENCRYPTION 
 ); 
  
 for 
  
 ( 
 google 
 :: 
 cloud 
 :: 
 KmsKeyName 
  
 const 
&  
 encryption_key 
  
 : 
  
 encryption_keys 
 ) 
  
 { 
  
 request 
 . 
 mutable_encryption_config 
 () 
 - 
> add_kms_key_names 
 ( 
  
 encryption_key 
 . 
 FullName 
 ()); 
  
 } 
  
 auto 
  
 backup 
  
 = 
  
 client 
 . 
 CreateBackup 
 ( 
 request 
 ). 
 get 
 (); 
  
 if 
  
 ( 
 ! 
 backup 
 ) 
  
 throw 
  
 std 
 :: 
 move 
 ( 
 backup 
 ). 
 status 
 (); 
  
 std 
 :: 
 cout 
 << 
 "Backup " 
 << 
 backup 
 - 
> name 
 () 
 << 
 " of " 
 << 
 backup 
 - 
> database 
 () 
 << 
 " of size " 
 << 
 backup 
 - 
> size_bytes 
 () 
 << 
 " bytes as of " 
 << 
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 MakeTimestamp 
 ( 
 backup 
 - 
> version_time 
 ()). 
 value 
 () 
 << 
 " was created at " 
 << 
 google 
 :: 
 cloud 
 :: 
 spanner 
 :: 
 MakeTimestamp 
 ( 
 backup 
 - 
> create_time 
 ()). 
 value 
 (); 
  
 PrintKmsKeys 
 ( 
 encryption_keys 
 ); 
 } 
 

Go

To create a CMEK-enabled backup in a regional instance configuration:

  import 
  
 ( 
  
 "context" 
  
 "fmt" 
  
 "io" 
  
 "regexp" 
  
 "time" 
  
 database 
  
 "cloud.google.com/go/spanner/admin/database/apiv1" 
  
 adminpb 
  
 "cloud.google.com/go/spanner/admin/database/apiv1/databasepb" 
  
 pbt 
  
 "github.com/golang/protobuf/ptypes/timestamp" 
 ) 
 func 
  
 createBackupWithCustomerManagedEncryptionKey 
 ( 
 ctx 
  
 context 
 . 
 Context 
 , 
  
 w 
  
 io 
 . 
 Writer 
 , 
  
 db 
 , 
  
 backupID 
 , 
  
 kmsKeyName 
  
 string 
 ) 
  
 error 
  
 { 
  
 // db = `projects/<project>/instances/<instance-id>/database/<database-id>` 
  
 // backupID = `my-backup-id` 
  
 // kmsKeyName = `projects/<project>/locations/<location>/keyRings/<key_ring>/cryptoKeys/<kms_key_name>` 
  
 matches 
  
 := 
  
 regexp 
 . 
 MustCompile 
 ( 
 "^(.+)/databases/(.+)$" 
 ). 
 FindStringSubmatch 
 ( 
 db 
 ) 
  
 if 
  
 matches 
  
 == 
  
 nil 
  
 || 
  
 len 
 ( 
 matches 
 ) 
  
 != 
  
 3 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createBackupWithCustomerManagedEncryptionKey: invalid database id %q" 
 , 
  
 db 
 ) 
  
 } 
  
 instanceName 
  
 := 
  
 matches 
 [ 
 1 
 ] 
  
 adminClient 
 , 
  
 err 
  
 := 
  
 database 
 . 
 NewDatabaseAdminClient 
 ( 
 ctx 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createBackupWithCustomerManagedEncryptionKey.NewDatabaseAdminClient: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 defer 
  
 adminClient 
 . 
  Close 
 
 () 
  
 expireTime 
  
 := 
  
 time 
 . 
 Now 
 (). 
 AddDate 
 ( 
 0 
 , 
  
 0 
 , 
  
 14 
 ) 
  
 // Create a backup for a database using a Customer Managed Encryption Key 
  
 req 
  
 := 
  
 adminpb 
 . 
 CreateBackupRequest 
 { 
  
 Parent 
 : 
  
 instanceName 
 , 
  
 BackupId 
 : 
  
 backupID 
 , 
  
 Backup 
 : 
  
& adminpb 
 . 
 Backup 
 { 
  
 Database 
 : 
  
 db 
 , 
  
 ExpireTime 
 : 
  
& pbt 
 . 
 Timestamp 
 { 
 Seconds 
 : 
  
 expireTime 
 . 
 Unix 
 (), 
  
 Nanos 
 : 
  
 int32 
 ( 
 expireTime 
 . 
 Nanosecond 
 ())}, 
  
 }, 
  
 EncryptionConfig 
 : 
  
& adminpb 
 . 
 CreateBackupEncryptionConfig 
 { 
  
 KmsKeyName 
 : 
  
 kmsKeyName 
 , 
  
 EncryptionType 
 : 
  
 adminpb 
 . 
 CreateBackupEncryptionConfig_CUSTOMER_MANAGED_ENCRYPTION 
 , 
  
 }, 
  
 } 
  
 op 
 , 
  
 err 
  
 := 
  
 adminClient 
 . 
 CreateBackup 
 ( 
 ctx 
 , 
  
& req 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createBackupWithCustomerManagedEncryptionKey.CreateBackup: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 // Wait for backup operation to complete. 
  
 backup 
 , 
  
 err 
  
 := 
  
 op 
 . 
 Wait 
 ( 
 ctx 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createBackupWithCustomerManagedEncryptionKey.Wait: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 // Get the name, create time, backup size and encryption key from the backup. 
  
 backupCreateTime 
  
 := 
  
 time 
 . 
 Unix 
 ( 
 backup 
 . 
 CreateTime 
 . 
 Seconds 
 , 
  
 int64 
 ( 
 backup 
 . 
 CreateTime 
 . 
 Nanos 
 )) 
  
 fmt 
 . 
 Fprintf 
 ( 
 w 
 , 
  
 "Backup %s of size %d bytes was created at %s using encryption key %s\n" 
 , 
  
 backup 
 . 
 Name 
 , 
  
 backup 
 . 
 SizeBytes 
 , 
  
 backupCreateTime 
 . 
 Format 
 ( 
 time 
 . 
 RFC3339 
 ), 
  
 kmsKeyName 
 ) 
  
 return 
  
 nil 
 } 
 

To create a CMEK-enabled backup in a multi-region instance configuration:

  import 
  
 ( 
  
 "context" 
  
 "fmt" 
  
 "io" 
  
 "time" 
  
 database 
  
 "cloud.google.com/go/spanner/admin/database/apiv1" 
  
 adminpb 
  
 "cloud.google.com/go/spanner/admin/database/apiv1/databasepb" 
  
 pbt 
  
 "github.com/golang/protobuf/ptypes/timestamp" 
 ) 
 // createBackupWithCustomerManagedMultiRegionEncryptionKey creates a backup for a database using a Customer Managed Multi-Region Encryption Key. 
 func 
  
 createBackupWithCustomerManagedMultiRegionEncryptionKey 
 ( 
 ctx 
  
 context 
 . 
 Context 
 , 
  
 w 
  
 io 
 . 
 Writer 
 , 
  
 projectID 
 , 
  
 instanceID 
 , 
  
 databaseID 
 , 
  
 backupID 
  
 string 
 , 
  
 kmsKeyNames 
  
 [] 
 string 
 ) 
  
 error 
  
 { 
  
 // projectID = `my-project` 
  
 // instanceID = `my-instance` 
  
 // databaseID = `my-database` 
  
 // backupID = `my-backup-id` 
  
 // kmsKeyNames := []string{"projects/my-project/locations/locations/<location1>/keyRings/<keyRing>/cryptoKeys/<keyId>", 
  
 //	 "projects/my-project/locations/locations/<location2>/keyRings/<keyRing>/cryptoKeys/<keyId>", 
  
 //	 "projects/my-project/locations/locations/<location3>/keyRings/<keyRing>/cryptoKeys/<keyId>", 
  
 // } 
  
 adminClient 
 , 
  
 err 
  
 := 
  
 database 
 . 
 NewDatabaseAdminClient 
 ( 
 ctx 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createBackupWithCustomerManagedMultiRegionEncryptionKey.NewDatabaseAdminClient: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 defer 
  
 adminClient 
 . 
  Close 
 
 () 
  
 expireTime 
  
 := 
  
 time 
 . 
 Now 
 (). 
 AddDate 
 ( 
 0 
 , 
  
 0 
 , 
  
 14 
 ) 
  
 // Create a backup for a database using a Customer Managed Encryption Key 
  
 req 
  
 := 
  
 adminpb 
 . 
 CreateBackupRequest 
 { 
  
 Parent 
 : 
  
 fmt 
 . 
 Sprintf 
 ( 
 "projects/%s/instances/%s" 
 , 
  
 projectID 
 , 
  
 instanceID 
 ), 
  
 BackupId 
 : 
  
 backupID 
 , 
  
 Backup 
 : 
  
& adminpb 
 . 
 Backup 
 { 
  
 Database 
 : 
  
 fmt 
 . 
 Sprintf 
 ( 
 "projects/%s/instances/%s/databases/%s" 
 , 
  
 projectID 
 , 
  
 instanceID 
 , 
  
 databaseID 
 ), 
  
 ExpireTime 
 : 
  
& pbt 
 . 
 Timestamp 
 { 
 Seconds 
 : 
  
 expireTime 
 . 
 Unix 
 (), 
  
 Nanos 
 : 
  
 int32 
 ( 
 expireTime 
 . 
 Nanosecond 
 ())}, 
  
 }, 
  
 EncryptionConfig 
 : 
  
& adminpb 
 . 
 CreateBackupEncryptionConfig 
 { 
  
 KmsKeyNames 
 : 
  
 kmsKeyNames 
 , 
  
 EncryptionType 
 : 
  
 adminpb 
 . 
 CreateBackupEncryptionConfig_CUSTOMER_MANAGED_ENCRYPTION 
 , 
  
 }, 
  
 } 
  
 op 
 , 
  
 err 
  
 := 
  
 adminClient 
 . 
 CreateBackup 
 ( 
 ctx 
 , 
  
& req 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createBackupWithCustomerManagedMultiRegionEncryptionKey.CreateBackup: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 // Wait for backup operation to complete. 
  
 backup 
 , 
  
 err 
  
 := 
  
 op 
 . 
 Wait 
 ( 
 ctx 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 return 
  
 fmt 
 . 
 Errorf 
 ( 
 "createBackupWithCustomerManagedMultiRegionEncryptionKey.Wait: %w" 
 , 
  
 err 
 ) 
  
 } 
  
 // Get the name, create time, backup size and encryption key from the backup. 
  
 backupCreateTime 
  
 := 
  
 time 
 . 
 Unix 
 ( 
 backup 
 . 
 CreateTime 
 . 
 Seconds 
 , 
  
 int64 
 ( 
 backup 
 . 
 CreateTime 
 . 
 Nanos 
 )) 
  
 fmt 
 . 
 Fprintf 
 ( 
 w 
 , 
  
 "Backup %s of size %d bytes was created at %s using multi-region encryption keys %q\n" 
 , 
  
 backup 
 . 
 Name 
 , 
  
 backup 
 . 
 SizeBytes 
 , 
  
 backupCreateTime 
 . 
 Format 
 ( 
 time 
 . 
 RFC3339 
 ), 
  
 kmsKeyNames 
 ) 
  
 return 
  
 nil 
 } 
 

Java

To create a CMEK-enabled backup in a regional instance configuration:

  import 
  
 com.google.cloud.spanner. Spanner 
 
 ; 
 import 
  
 com.google.cloud.spanner. SpannerExceptionFactory 
 
 ; 
 import 
  
 com.google.cloud.spanner. SpannerOptions 
 
 ; 
 import 
  
 com.google.cloud.spanner.admin.database.v1. DatabaseAdminClient 
 
 ; 
 import 
  
 com.google.protobuf. Timestamp 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. Backup 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. BackupName 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. CreateBackupEncryptionConfig 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. CreateBackupEncryptionConfig 
.EncryptionType 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. CreateBackupRequest 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. DatabaseName 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. InstanceName 
 
 ; 
 import 
  
 java.util.concurrent.ExecutionException 
 ; 
 import 
  
 java.util.concurrent.TimeUnit 
 ; 
 import 
  
 java.util.concurrent.TimeoutException 
 ; 
 import 
  
 org.threeten.bp.LocalDateTime 
 ; 
 import 
  
 org.threeten.bp.OffsetDateTime 
 ; 
 public 
  
 class 
 CreateBackupWithEncryptionKey 
  
 { 
  
 static 
  
 void 
  
 createBackupWithEncryptionKey 
 () 
  
 { 
  
 // TODO(developer): Replace these variables before running the sample. 
  
 String 
  
 projectId 
  
 = 
  
 "my-project" 
 ; 
  
 String 
  
 instanceId 
  
 = 
  
 "my-instance" 
 ; 
  
 String 
  
 databaseId 
  
 = 
  
 "my-database" 
 ; 
  
 String 
  
 backupId 
  
 = 
  
 "my-backup" 
 ; 
  
 String 
  
 kmsKeyName 
  
 = 
  
 "projects/" 
  
 + 
  
 projectId 
  
 + 
  
 "/locations/<location>/keyRings/<keyRing>/cryptoKeys/<keyId>" 
 ; 
  
 try 
  
 ( 
  Spanner 
 
  
 spanner 
  
 = 
  
  SpannerOptions 
 
 . 
 newBuilder 
 (). 
 setProjectId 
 ( 
 projectId 
 ). 
 build 
 (). 
 getService 
 (); 
  
  DatabaseAdminClient 
 
  
 adminClient 
  
 = 
  
 spanner 
 . 
  createDatabaseAdminClient 
 
 ()) 
  
 { 
  
 createBackupWithEncryptionKey 
 ( 
  
 adminClient 
 , 
  
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 , 
  
 backupId 
 , 
  
 kmsKeyName 
 ); 
  
 } 
  
 } 
  
 static 
  
 Void 
  
 createBackupWithEncryptionKey 
 ( 
  DatabaseAdminClient 
 
  
 adminClient 
 , 
  
 String 
  
 projectId 
 , 
  
 String 
  
 instanceId 
 , 
  
 String 
  
 databaseId 
 , 
  
 String 
  
 backupId 
 , 
  
 String 
  
 kmsKeyName 
 ) 
  
 { 
  
 // Set expire time to 14 days from now. 
  
 final 
  
  Timestamp 
 
  
 expireTime 
  
 = 
  
  Timestamp 
 
 . 
 newBuilder 
 (). 
 setSeconds 
 ( 
 TimeUnit 
 . 
 MILLISECONDS 
 . 
 toSeconds 
 (( 
  
 System 
 . 
 currentTimeMillis 
 () 
  
 + 
  
 TimeUnit 
 . 
 DAYS 
 . 
 toMillis 
 ( 
 14 
 )))). 
 build 
 (); 
  
 final 
  
  BackupName 
 
  
 backupName 
  
 = 
  
  BackupName 
 
 . 
 of 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 backupId 
 ); 
  
  Backup 
 
  
 backup 
  
 = 
  
  Backup 
 
 . 
 newBuilder 
 () 
  
 . 
 setName 
 ( 
 backupName 
 . 
  toString 
 
 ()) 
  
 . 
 setDatabase 
 ( 
  DatabaseName 
 
 . 
 of 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 ). 
 toString 
 ()) 
  
 . 
 setExpireTime 
 ( 
 expireTime 
 ). 
 build 
 (); 
  
 final 
  
  CreateBackupRequest 
 
  
 request 
  
 = 
  
  CreateBackupRequest 
 
 . 
 newBuilder 
 () 
  
 . 
 setParent 
 ( 
  InstanceName 
 
 . 
 of 
 ( 
 projectId 
 , 
  
 instanceId 
 ). 
 toString 
 ()) 
  
 . 
 setBackupId 
 ( 
 backupId 
 ) 
  
 . 
 setBackup 
 ( 
 backup 
 ) 
  
 . 
 setEncryptionConfig 
 ( 
  
  CreateBackupEncryptionConfig 
 
 . 
 newBuilder 
 () 
  
 . 
 setEncryptionType 
 ( 
 EncryptionType 
 . 
 CUSTOMER_MANAGED_ENCRYPTION 
 ) 
  
 . 
 setKmsKeyName 
 ( 
 kmsKeyName 
 ). 
 build 
 ()). 
 build 
 (); 
  
 try 
  
 { 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Waiting for operation to complete..." 
 ); 
  
 backup 
  
 = 
  
 adminClient 
 . 
  createBackupAsync 
 
 ( 
 request 
 ). 
 get 
 ( 
 1200 
 , 
  
 TimeUnit 
 . 
 SECONDS 
 ); 
  
 } 
  
 catch 
  
 ( 
 ExecutionException 
  
 e 
 ) 
  
 { 
  
 // If the operation failed during execution, expose the cause. 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  asSpannerException 
 
 ( 
 e 
 . 
 getCause 
 ()); 
  
 } 
  
 catch 
  
 ( 
 InterruptedException 
  
 e 
 ) 
  
 { 
  
 // Throw when a thread is waiting, sleeping, or otherwise occupied, 
  
 // and the thread is interrupted, either before or during the activity. 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  propagateInterrupt 
 
 ( 
 e 
 ); 
  
 } 
  
 catch 
  
 ( 
 TimeoutException 
  
 e 
 ) 
  
 { 
  
 // If the operation timed out propagates the timeout 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  propagateTimeout 
 
 ( 
 e 
 ); 
  
 } 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Backup %s of size %d bytes was created at %s using encryption key %s%n" 
 , 
  
  backup 
 
 . 
  getName 
 
 (), 
  
  backup 
 
 . 
  getSizeBytes 
 
 (), 
  
 LocalDateTime 
 . 
 ofEpochSecond 
 ( 
  
  backup 
 
 . 
  getCreateTime 
 
 (). 
 getSeconds 
 (), 
  
  backup 
 
 . 
  getCreateTime 
 
 (). 
 getNanos 
 (), 
  
 OffsetDateTime 
 . 
 now 
 (). 
 getOffset 
 ()), 
  
 kmsKeyName 
  
 ); 
  
 return 
  
 null 
 ; 
  
 } 
 } 
 

To create a CMEK-enabled backup in a multi-region instance configuration:

  import 
  
 com.google.cloud.spanner. Spanner 
 
 ; 
 import 
  
 com.google.cloud.spanner. SpannerExceptionFactory 
 
 ; 
 import 
  
 com.google.cloud.spanner. SpannerOptions 
 
 ; 
 import 
  
 com.google.cloud.spanner.admin.database.v1. DatabaseAdminClient 
 
 ; 
 import 
  
 com.google.common.collect.ImmutableList 
 ; 
 import 
  
 com.google.protobuf. Timestamp 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. Backup 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. BackupName 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. CreateBackupEncryptionConfig 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. CreateBackupEncryptionConfig 
.EncryptionType 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. CreateBackupRequest 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. DatabaseName 
 
 ; 
 import 
  
 com.google.spanner.admin.database.v1. InstanceName 
 
 ; 
 import 
  
 java.util.concurrent.ExecutionException 
 ; 
 import 
  
 java.util.concurrent.TimeUnit 
 ; 
 import 
  
 java.util.concurrent.TimeoutException 
 ; 
 import 
  
 org.threeten.bp.LocalDateTime 
 ; 
 import 
  
 org.threeten.bp.OffsetDateTime 
 ; 
 public 
  
 class 
 CreateBackupWithMultiRegionEncryptionKey 
  
 { 
  
 static 
  
 void 
  
 createBackupWithMultiRegionEncryptionKey 
 () 
  
 { 
  
 // TODO(developer): Replace these variables before running the sample. 
  
 String 
  
 projectId 
  
 = 
  
 "my-project" 
 ; 
  
 String 
  
 instanceId 
  
 = 
  
 "my-instance" 
 ; 
  
 String 
  
 databaseId 
  
 = 
  
 "my-database" 
 ; 
  
 String 
  
 backupId 
  
 = 
  
 "my-backup" 
 ; 
  
 String 
 [] 
  
 kmsKeyNames 
  
 = 
  
 new 
  
 String 
 [] 
  
 { 
  
 "projects/" 
  
 + 
  
 projectId 
  
 + 
  
 "/locations/<location1>/keyRings/<keyRing>/cryptoKeys/<keyId>" 
 , 
  
 "projects/" 
  
 + 
  
 projectId 
  
 + 
  
 "/locations/<location2>/keyRings/<keyRing>/cryptoKeys/<keyId>" 
 , 
  
 "projects/" 
  
 + 
  
 projectId 
  
 + 
  
 "/locations/<location3>/keyRings/<keyRing>/cryptoKeys/<keyId>" 
  
 }; 
  
 try 
  
 ( 
  Spanner 
 
  
 spanner 
  
 = 
  
  SpannerOptions 
 
 . 
 newBuilder 
 (). 
 setProjectId 
 ( 
 projectId 
 ). 
 build 
 (). 
 getService 
 (); 
  
  DatabaseAdminClient 
 
  
 adminClient 
  
 = 
  
 spanner 
 . 
  createDatabaseAdminClient 
 
 ()) 
  
 { 
  
 createBackupWithMultiRegionEncryptionKey 
 ( 
  
 adminClient 
 , 
  
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 , 
  
 backupId 
 , 
  
 kmsKeyNames 
 ); 
  
 } 
  
 } 
  
 static 
  
 Void 
  
 createBackupWithMultiRegionEncryptionKey 
 ( 
  
  DatabaseAdminClient 
 
  
 adminClient 
 , 
  
 String 
  
 projectId 
 , 
  
 String 
  
 instanceId 
 , 
  
 String 
  
 databaseId 
 , 
  
 String 
  
 backupId 
 , 
  
 String 
 [] 
  
 kmsKeyNames 
 ) 
  
 { 
  
 // Set expire time to 14 days from now. 
  
 final 
  
  Timestamp 
 
  
 expireTime 
  
 = 
  
  Timestamp 
 
 . 
 newBuilder 
 () 
  
 . 
 setSeconds 
 ( 
  
 TimeUnit 
 . 
 MILLISECONDS 
 . 
 toSeconds 
 ( 
  
 ( 
 System 
 . 
 currentTimeMillis 
 () 
  
 + 
  
 TimeUnit 
 . 
 DAYS 
 . 
 toMillis 
 ( 
 14 
 )))) 
  
 . 
 build 
 (); 
  
 final 
  
  BackupName 
 
  
 backupName 
  
 = 
  
  BackupName 
 
 . 
 of 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 backupId 
 ); 
  
  Backup 
 
  
 backup 
  
 = 
  
  Backup 
 
 . 
 newBuilder 
 () 
  
 . 
 setName 
 ( 
 backupName 
 . 
  toString 
 
 ()) 
  
 . 
 setDatabase 
 ( 
  DatabaseName 
 
 . 
 of 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 ). 
 toString 
 ()) 
  
 . 
 setExpireTime 
 ( 
 expireTime 
 ) 
  
 . 
 build 
 (); 
  
 final 
  
  CreateBackupRequest 
 
  
 request 
  
 = 
  
  CreateBackupRequest 
 
 . 
 newBuilder 
 () 
  
 . 
 setParent 
 ( 
  InstanceName 
 
 . 
 of 
 ( 
 projectId 
 , 
  
 instanceId 
 ). 
 toString 
 ()) 
  
 . 
 setBackupId 
 ( 
 backupId 
 ) 
  
 . 
 setBackup 
 ( 
 backup 
 ) 
  
 . 
 setEncryptionConfig 
 ( 
  
  CreateBackupEncryptionConfig 
 
 . 
 newBuilder 
 () 
  
 . 
 setEncryptionType 
 ( 
 EncryptionType 
 . 
 CUSTOMER_MANAGED_ENCRYPTION 
 ) 
  
 . 
 addAllKmsKeyNames 
 ( 
 ImmutableList 
 . 
 copyOf 
 ( 
 kmsKeyNames 
 )) 
  
 . 
 build 
 ()) 
  
 . 
 build 
 (); 
  
 try 
  
 { 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Waiting for operation to complete..." 
 ); 
  
 backup 
  
 = 
  
 adminClient 
 . 
  createBackupAsync 
 
 ( 
 request 
 ). 
 get 
 ( 
 1200 
 , 
  
 TimeUnit 
 . 
 SECONDS 
 ); 
  
 } 
  
 catch 
  
 ( 
 ExecutionException 
  
 e 
 ) 
  
 { 
  
 // If the operation failed during execution, expose the cause. 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  asSpannerException 
 
 ( 
 e 
 . 
 getCause 
 ()); 
  
 } 
  
 catch 
  
 ( 
 InterruptedException 
  
 e 
 ) 
  
 { 
  
 // Throw when a thread is waiting, sleeping, or otherwise occupied, 
  
 // and the thread is interrupted, either before or during the activity. 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  propagateInterrupt 
 
 ( 
 e 
 ); 
  
 } 
  
 catch 
  
 ( 
 TimeoutException 
  
 e 
 ) 
  
 { 
  
 // If the operation timed out propagates the timeout 
  
 throw 
  
  SpannerExceptionFactory 
 
 . 
  propagateTimeout 
 
 ( 
 e 
 ); 
  
 } 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Backup %s of size %d bytes was created at %s using encryption keys %s%n" 
 , 
  
  backup 
 
 . 
  getName 
 
 (), 
  
  backup 
 
 . 
  getSizeBytes 
 
 (), 
  
 LocalDateTime 
 . 
 ofEpochSecond 
 ( 
  
  backup 
 
 . 
  getCreateTime 
 
 (). 
 getSeconds 
 (), 
  
  backup 
 
 . 
  getCreateTime 
 
 (). 
 getNanos 
 (), 
  
 OffsetDateTime 
 . 
 now 
 (). 
 getOffset 
 ()), 
  
 ImmutableList 
 . 
 copyOf 
 ( 
 kmsKeyNames 
 )); 
  
 return 
  
 null 
 ; 
  
 } 
 } 
 

Node.js

To create a CMEK-enabled backup in a regional instance configuration:

  // Imports the Google Cloud client library 
 const 
  
 { 
 Spanner 
 , 
  
 protos 
 } 
  
 = 
  
 require 
 ( 
 ' @google-cloud/spanner 
' 
 ); 
 const 
  
 { 
 PreciseDate 
 } 
  
 = 
  
 require 
 ( 
 ' @google-cloud/precise-date 
' 
 ); 
 /** 
 * TODO(developer): Uncomment the following lines before running the sample. 
 */ 
 // const projectId = 'my-project-id'; 
 // const instanceId = 'my-instance'; 
 // const databaseId = 'my-database'; 
 // const backupId = 'my-backup'; 
 // const keyName = 
 //   'projects/my-project-id/my-region/keyRings/my-key-ring/cryptoKeys/my-key'; 
 // Creates a client 
 const 
  
 spanner 
  
 = 
  
 new 
  
  Spanner 
 
 ({ 
  
 projectId 
 : 
  
 projectId 
 , 
 }); 
 // Gets a reference to a Cloud Spanner Database Admin Client object 
 const 
  
 databaseAdminClient 
  
 = 
  
 spanner 
 . 
  getDatabaseAdminClient 
 
 (); 
 // Creates a new backup of the database 
 try 
  
 { 
  
 console 
 . 
 log 
 ( 
  
 `Creating backup of database 
 ${ 
 databaseAdminClient 
 . 
 databasePath 
 ( 
  
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 , 
  
 ) 
 } 
 .` 
 , 
  
 ); 
  
 // Expire backup 14 days in the future 
  
 const 
  
 expireTime 
  
 = 
  
 Date 
 . 
 now 
 () 
  
 + 
  
 1000 
  
 * 
  
 60 
  
 * 
  
 60 
  
 * 
  
 24 
  
 * 
  
 14 
 ; 
  
 // Create a backup of the state of the database at the current time. 
  
 const 
  
 [ 
 operation 
 ] 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
 createBackup 
 ({ 
  
 parent 
 : 
  
 databaseAdminClient 
 . 
 instancePath 
 ( 
 projectId 
 , 
  
 instanceId 
 ), 
  
 backupId 
 : 
  
 backupId 
 , 
  
 backup 
 : 
  
 ( 
 protos 
 . 
 google 
 . 
 spanner 
 . 
 admin 
 . 
 database 
 . 
 v1 
 . 
  Backup 
 
  
 = 
  
 { 
  
 database 
 : 
  
 databaseAdminClient 
 . 
 databasePath 
 ( 
  
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 , 
  
 ), 
  
 expireTime 
 : 
  
  Spanner 
 
 . 
  timestamp 
 
 ( 
 expireTime 
 ). 
  toStruct 
 
 (), 
  
 name 
 : 
  
 databaseAdminClient 
 . 
  backupPath 
 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 backupId 
 ), 
  
 }), 
  
 encryptionConfig 
 : 
  
 { 
  
 encryptionType 
 : 
  
 'CUSTOMER_MANAGED_ENCRYPTION' 
 , 
  
 kmsKeyName 
 : 
  
 keyName 
 , 
  
 }, 
  
 }); 
  
 console 
 . 
 log 
 ( 
  
 `Waiting for backup 
 ${ 
 databaseAdminClient 
 . 
  backupPath 
 
 ( 
  
 projectId 
 , 
  
 instanceId 
 , 
  
 backupId 
 , 
  
 ) 
 } 
 to complete...` 
 , 
  
 ); 
  
 await 
  
  operation 
 
 . 
 promise 
 (); 
  
 // Verify backup is ready 
  
 const 
  
 [ 
 backupInfo 
 ] 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
 getBackup 
 ({ 
  
 name 
 : 
  
 databaseAdminClient 
 . 
  backupPath 
 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 backupId 
 ), 
  
 }); 
  
 if 
  
 ( 
 backupInfo 
 . 
 state 
  
 === 
  
 'READY' 
 ) 
  
 { 
  
 console 
 . 
 log 
 ( 
  
 `Backup 
 ${ 
 backupInfo 
 . 
 name 
 } 
 of size ` 
  
 + 
  
 ` 
 ${ 
 backupInfo 
 . 
 sizeBytes 
 } 
 bytes was created at ` 
  
 + 
  
 ` 
 ${ 
 new 
  
  PreciseDate 
 
 ( 
 backupInfo 
 . 
 createTime 
 ). 
  toISOString 
 
 () 
 } 
 ` 
  
 + 
  
 `using encryption key 
 ${ 
 backupInfo 
 . 
 encryptionInfo 
 . 
 kmsKeyVersion 
 } 
 ` 
 , 
  
 ); 
  
 } 
  
 else 
  
 { 
  
 console 
 . 
 error 
 ( 
 'ERROR: Backup is not ready.' 
 ); 
  
 } 
 } 
  
 catch 
  
 ( 
 err 
 ) 
  
 { 
  
 console 
 . 
 error 
 ( 
 'ERROR:' 
 , 
  
 err 
 ); 
 } 
  
 finally 
  
 { 
  
 // Close the spanner client when finished. 
  
 // The databaseAdminClient does not require explicit closure. The closure of the Spanner client will automatically close the databaseAdminClient. 
  
 spanner 
 . 
 close 
 (); 
 } 
 

To create a CMEK-enabled backup in a multi-region instance configuration:

  /** 
 * TODO(developer): Uncomment the following lines before running the sample. 
 */ 
 // const projectId = 'my-project-id'; 
 // const instanceId = 'my-instance'; 
 // const databaseId = 'my-database'; 
 // const backupId = 'my-backup'; 
 // const kmsKeyNames = 
 //   'projects/my-project-id/my-region/keyRings/my-key-ring/cryptoKeys/my-key1, 
 //   'projects/my-project-id/my-region/keyRings/my-key-ring/cryptoKeys/my-key2'; 
 // Imports the Google Cloud client library 
 const 
  
 { 
 Spanner 
 , 
  
 protos 
 } 
  
 = 
  
 require 
 ( 
 ' @google-cloud/spanner 
' 
 ); 
 const 
  
 { 
 PreciseDate 
 } 
  
 = 
  
 require 
 ( 
 ' @google-cloud/precise-date 
' 
 ); 
 // Creates a client 
 const 
  
 spanner 
  
 = 
  
 new 
  
  Spanner 
 
 ({ 
  
 projectId 
 : 
  
 projectId 
 , 
 }); 
 // Gets a reference to a Cloud Spanner Database Admin Client object 
 const 
  
 databaseAdminClient 
  
 = 
  
 spanner 
 . 
  getDatabaseAdminClient 
 
 (); 
 async 
  
 function 
  
 createBackupWithMultipleKmsKeys 
 () 
  
 { 
  
 // Creates a new backup of the database 
  
 try 
  
 { 
  
 console 
 . 
 log 
 ( 
  
 `Creating backup of database 
 ${ 
 databaseAdminClient 
 . 
 databasePath 
 ( 
  
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 , 
  
 ) 
 } 
 .` 
 , 
  
 ); 
  
 // Expire backup 14 days in the future 
  
 const 
  
 expireTime 
  
 = 
  
 Date 
 . 
 now 
 () 
  
 + 
  
 1000 
  
 * 
  
 60 
  
 * 
  
 60 
  
 * 
  
 24 
  
 * 
  
 14 
 ; 
  
 // Create a backup of the state of the database at the current time. 
  
 const 
  
 [ 
 operation 
 ] 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
 createBackup 
 ({ 
  
 parent 
 : 
  
 databaseAdminClient 
 . 
 instancePath 
 ( 
 projectId 
 , 
  
 instanceId 
 ), 
  
 backupId 
 : 
  
 backupId 
 , 
  
 backup 
 : 
  
 ( 
 protos 
 . 
 google 
 . 
 spanner 
 . 
 admin 
 . 
 database 
 . 
 v1 
 . 
  Backup 
 
  
 = 
  
 { 
  
 database 
 : 
  
 databaseAdminClient 
 . 
 databasePath 
 ( 
  
 projectId 
 , 
  
 instanceId 
 , 
  
 databaseId 
 , 
  
 ), 
  
 expireTime 
 : 
  
  Spanner 
 
 . 
  timestamp 
 
 ( 
 expireTime 
 ). 
  toStruct 
 
 (), 
  
 name 
 : 
  
 databaseAdminClient 
 . 
  backupPath 
 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 backupId 
 ), 
  
 }), 
  
 encryptionConfig 
 : 
  
 { 
  
 encryptionType 
 : 
  
 'CUSTOMER_MANAGED_ENCRYPTION' 
 , 
  
 kmsKeyNames 
 : 
  
 kmsKeyNames 
 . 
 split 
 ( 
 ',' 
 ), 
  
 }, 
  
 }); 
  
 console 
 . 
 log 
 ( 
  
 `Waiting for backup 
 ${ 
 databaseAdminClient 
 . 
  backupPath 
 
 ( 
  
 projectId 
 , 
  
 instanceId 
 , 
  
 backupId 
 , 
  
 ) 
 } 
 to complete...` 
 , 
  
 ); 
  
 await 
  
  operation 
 
 . 
 promise 
 (); 
  
 // Verify backup is ready 
  
 const 
  
 [ 
 backupInfo 
 ] 
  
 = 
  
 await 
  
 databaseAdminClient 
 . 
 getBackup 
 ({ 
  
 name 
 : 
  
 databaseAdminClient 
 . 
  backupPath 
 
 ( 
 projectId 
 , 
  
 instanceId 
 , 
  
 backupId 
 ), 
  
 }); 
  
 const 
  
 kmsKeyVersions 
  
 = 
  
 backupInfo 
 . 
 encryptionInformation 
  
 . 
 map 
 ( 
 encryptionInfo 
  
 = 
>  
 encryptionInfo 
 . 
 kmsKeyVersion 
 ) 
  
 . 
 join 
 ( 
 ', ' 
 ); 
  
 if 
  
 ( 
 backupInfo 
 . 
 state 
  
 === 
  
 'READY' 
 ) 
  
 { 
  
 console 
 . 
 log 
 ( 
  
 `Backup 
 ${ 
 backupInfo 
 . 
 name 
 } 
 of size ` 
  
 + 
  
 ` 
 ${ 
 backupInfo 
 . 
 sizeBytes 
 } 
 bytes was created at ` 
  
 + 
  
 ` 
 ${ 
 new 
  
  PreciseDate 
 
 ( 
 backupInfo 
 . 
 createTime 
 ). 
  toISOString 
 
 () 
 } 
 ` 
  
 + 
  
 `using encryption key 
 ${ 
 kmsKeyVersions 
 } 
 ` 
 , 
  
 ); 
  
 } 
  
 else 
  
 { 
  
 console 
 . 
 error 
 ( 
 'ERROR: Backup is not ready.' 
 ); 
  
 } 
  
 } 
  
 catch 
  
 ( 
 err 
 ) 
  
 { 
  
 console 
 . 
 error 
 ( 
 'ERROR:' 
 , 
  
 err 
 ); 
  
 } 
  
 finally 
  
 { 
  
 // Close the spanner client when finished. 
  
 // The databaseAdminClient does not require explicit closure. The closure of the Spanner client will automatically close the databaseAdminClient. 
  
 spanner 
 . 
 close 
 (); 
  
 } 
 } 
 createBackupWithMultipleKmsKeys 
 (); 
 

PHP

To create a CMEK-enabled backup in a regional instance configuration:

   
 
Design a Mobile Site
View Site in Mobile | Classic
Share by: