Protecting Resources with Cloud KMS Keys

By default, Compute Engine encrypts customer content at rest. Compute Engine handles and manages this encryption for you without any additional actions on your part. However, if you want to control and manage this encryption yourself, you can use key encryption keys. Key encryption keys do not directly encrypt your data but are used to encrypt the data encryption keys that encrypt your data.

You have two options for key encryption keys in Compute Engine:

After you create a Compute Engine resource that is protected by Cloud KMS, you do not need to specify the key because Compute Engine knows which KMS key was used. This is different from how Compute Engine accesses resources protected by customer-supplied keys. For that access, you need to specify the customer-supplied key.

Learn more about encryption options on Google Cloud Platform.

Before you begin

  1. Understand disks, images, persistent disk snapshots, and instances.

  2. Decide whether you are going to run Compute Engine and Cloud KMS in the same Google Cloud Platform project, or in different projects. For documentation example purposes, the following convention is used:

    • [PROJECT_ID] is the project ID of the project running Compute Engine
    • [PROJECT_NUMBER] is the project number of the project running Compute Engine
    • [KMS_PROJECT_ID] is the project ID of the project running Cloud KMS (even if this is the same project running Compute Engine)
    For information about GCP project IDs and project numbers, see Identifying projects.

  3. For the GCP project that runs Compute Engine, set up API access for Compute Engine.

  4. For the GCP project that runs Cloud KMS:

    1. enable the Cloud KMS API.
    2. create a key ring and a key as described in Creating Key Rings and Keys.

  5. Assign the Cloud KMS CryptoKey Encrypter/Decrypter role to the Compute Engine Service Agent. This account is of the form

    service-[PROJECT_NUMBER]@compute-system.iam.gserviceaccount.com
    
    You can use the gcloud command-line tool to assign the role:
    gcloud projects add-iam-policy-binding [KMS_PROJECT_ID] \
    --member serviceAccount:service-[PROJECT_NUMBER]@compute-system.iam.gserviceaccount.com \
    --role roles/cloudkms.cryptoKeyEncrypterDecrypter
    
    Replace [KMS_PROJECT_ID] with the ID of your GCP project that is running Cloud KMS, and replace [PROJECT_NUMBER] with the project number (not project ID) of your GCP project that is running the Compute Engine resources.

Specifications

Encryption

Cloud KMS keys used to protect your data in Compute Engine are AES-256 keys. These keys are key encryption keys, and they encrypt the data encryption keys that encrypt your data.

Restrictions

  • You can encrypt only new persistent disks, images, and snapshots with your own key. You cannot encrypt existing resources with your own key.

  • You cannot use your own keys with local SSDs because local SSDs do not persist beyond the life of a virtual machine. Local SSDs are already protected with an ephemeral encryption key that Google does not retain.

Encrypt a new persistent disk with your own keys

You can encrypt a new persistent disk by supplying a key during instance or disk creation.

Console

  1. In the Google Cloud Platform Console, go to the Disks page.

    Go to the Disks page

  2. Click Create disk and enter the properties for the new disk.
  3. Under Encryption, select Customer-managed key.
  4. Use the dropdown menu to select the Cloud KMS key to use to encrypt this disk.
  5. Click Create to create the disk.

Command-line

gcloud beta compute disks \
create encrypted-disk \
--kms-key projects/[KMS_PROJECT_ID]/locations/[REGION]/keyRings/[KEY_RING]/cryptoKeys/[KEY]

API

Encrypt a disk using the diskEncryptionKey property with the kmsKeyName property. For example, to encrypt a new disk during instance creation with your Cloud KMS key:

POST
https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances

{ "machineType": "zones/[ZONE]/machineTypes/n1-standard-1", "disks": [ { "type": "PERSISTENT", "diskEncryptionKey": { "kmsKeyName": "projects/[KMS_PROJECT_ID]/locations/[REGION]/keyRings/[KEY_RING]/cryptoKeys/[KEY]" }, "initializeParams": { "sourceImage": "projects/debian-cloud/global/images/debian-8-jessie-v20160301" }, "boot": true } ], ... }

Similarly, you can also use the API to create a new stand-alone persistent disk and encrypt it with your Cloud KMS key:

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/
[ZONE]/disks?sourceImage=https%3A%2F%2Fwww.googleapis.com%2Fcompute%2F
projects%2Fdebian-cloud%2Fglobal%2Fimages%2Fdebian-8-jessie-v20160301

{ "name": "new-encrypted-disk-key", "diskEncryptionKey": { "kmsKeyName": "projects/[KMS_PROJECT_ID]/locations/[REGION]/keyRings/[KEY_RING]/cryptoKeys/[KEY]" }, "type": "zones/[ZONE]/diskTypes/pd-standard" }

Create a snapshot from an encrypted disk

When you create a snapshot from a disk encrypted with CMEK, the snapshot must be protected by the same encryption key that you used to encrypt the disk.

Console

  1. In the Google Cloud Platform Console, go to the Snapshots page.

    Go to the Snapshots page

  2. Click Create snapshot.
  3. Under Source disk, choose the source disk for the snapshot. The snapshot will automatically be encrypted with the same key used by the source disk.

Command-line

gcloud beta compute \
disks snapshot encrypted-disk \
--zone [ZONE]

API

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/disks/example-disk/createSnapshot

{ "snapshotEncryptionKey": { "kmsKeyName": "projects/[KMS_PROJECT_ID]/locations/[REGION]/keyRings/[KEY_RING]/cryptoKeys/[SNAPSHOT_KEY]" }, "name": "snapshot-encrypted-disk" }

You cannot create a snapshot that is protected by CMEK unless the disk itself is already protected by CMEK. Also, you cannot convert encrypted disks or encrypted snapshots to use Compute Engine default encryption unless you create a completely new disk image and a new persistent disk.

Encrypt an imported image

You can encrypt a new image when you import a custom image to Compute Engine. Before you can import an image, you must create and compress a disk image file and upload that compressed file to Google Cloud Storage.

Console

  1. In the Google Cloud Platform Console, go to the Images page.

    Go to the Images page

  2. Click Create image.
  3. Under Source disk, select the disk you want to create an image of.
  4. Under Encryption, select Customer-managed key.
  5. Use the dropdown menu to select the Cloud KMS key to use to encrypt this image.
  6. Continue with the image creation process.

Command-line

gcloud beta compute \
images create [...] \
--kms-key projects/[KMS_PROJECT_ID]/locations/[REGION]/keyRings/[KEY_RING]/cryptoKeys/[KEY]

API

To encrypt an imported image, specify the URI to the compressed file, add the imageEncryptionKey property to the image creation request, and specify the key to encrypt the image in the kmsKeyName property:

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/images

{ "rawDisk": { "source": "http://storage.googleapis.com/example-image/example-image.tar.gz" }, "name": "new-encrypted-image", "sourceType": "RAW", "imageEncryptionKey": { "kmsKeyName": "projects/[KMS_PROJECT_ID]/locations/[REGION]/keyRings/[KEY_RING]/cryptoKeys/[IMAGE_KEY]" } }

Create a persistent disk from an encrypted resource

Create a disk from an encrypted snapshot

To create a new standalone persistent disk using an encrypted snapshot:

Console

  1. In the Google Cloud Platform Console, go to the Disks page.

    Go to the Disks page

  2. Click Create disk and enter the properties for the new disk.
  3. Under Source type, select the desired snapshot or image.
  4. Continue with the persistent disk creation process.

Command-line

gcloud (beta) compute \
disks create [...] \
--source-snapshot example-snapshot \
--kms-key projects/[KMS_PROJECT_ID]/locations/[REGION]/keyRings/[KEY_RING]/cryptoKeys/[KEY]

To use an image instead of a snapshot, replace --source-snapshot example-snapshot with --image example-image.

API

POST https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/disks

{ "name": "disk-from-encrypted-snapshot", "sourceSnapshot": "global/snapshots/encrypted-snapshot" }

Attaching an encrypted disk to a new instance

Console

  1. In the Google Cloud Platform Console, go to the VM instances page.

    Go to the VM instances page

  2. Click Create instance.
  3. Under Boot disk, click Change.
  4. Click Existing disks.
  5. Select an existing disk to attach to the instance.
  6. Continue with the instance creation process.

Command-line

gcloud beta compute instances \
create example-instance \
--disk name=encrypted-disk,boot=yes

API

"disks": [
{
  "deviceName": "encrypted-disk",
  "source": "projects/[PROJECT_ID]/zones/[ZONE]/disks/encrypted-disk"
  }
 }
]

Remove your Cloud KMS encryption key from a persistent disk

You can decrypt the contents of a encrypted disk and create a new disk that uses Compute Engine default encryption instead.

  1. Create an image of the encrypted disk and specify automatic encryption for the new image.
  2. Use the new image to create a new persistent disk.

After you create the new persistent disk, it uses Compute Engine default encryption to protect the disk contents. Any snapshots that you create from that disk must also use default encryption.

Impact of disabling or enabling encryption keys

Disabling or deleting an encryption key will have the following effects on content protected by that key:

  • VMs with attached disks that are protected by the key cannot boot
  • Disks protected by the key cannot be attached to virtual machines, nor can snapshots be created for them
  • Snapshots protected by the key cannot be used to create a disk
  • Images protected by the key cannot be used to create a disk

If you disable the key, the effects above can be reversed by enabling the key. If you delete the key, the effects above are irreversible.

Limitations

  • Regional resources (disks) can be encrypted by keys in the same location or in the global location. For example, a disk in zone us-west1-a can be encrypted by a key in us-west1 or global. Global resources (images, snapshots) can be encrypted by keys in any location.
Was this page helpful? Let us know how we did:

Send feedback about...

Compute Engine Documentation