support KMS encryption for instance templates

This commit is contained in:
Chris Stephens 2018-10-26 01:05:56 +00:00 committed by Nathan McKinley
parent 4af9af26d6
commit 9be729fb78
4 changed files with 162 additions and 36 deletions

View File

@ -342,42 +342,6 @@ func TestAccComputeDisk_encryption(t *testing.T) {
})
}
func TestAccComputeDisk_encryptionKMS(t *testing.T) {
t.Parallel()
org := getTestOrgFromEnv(t)
pid := "tf-test-" + acctest.RandString(10)
billingAccount := getTestBillingAccountFromEnv(t)
diskName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
keyRingName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
keyName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
importID := fmt.Sprintf("%s/%s/%s", pid, "us-central1-a", diskName)
var disk compute.Disk
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeDiskDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeDisk_encryptionKMS(pid, pname, org, billingAccount, diskName, keyRingName, keyName),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeDiskExists(
"google_compute_disk.foobar", pid, &disk),
testAccCheckEncryptionKey(
"google_compute_disk.foobar", &disk),
),
},
resource.TestStep{
ResourceName: "google_compute_disk.foobar",
ImportStateId: importID,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccComputeDisk_deleteDetach(t *testing.T) {
t.Parallel()

View File

@ -131,6 +131,23 @@ func resourceComputeInstanceTemplate() *schema.Resource {
ForceNew: true,
Computed: true,
},
"disk_encryption_key": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"kms_key_self_link": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
DiffSuppressFunc: compareSelfLinkRelativePaths,
},
},
},
},
},
},
},
@ -500,6 +517,13 @@ func buildDisks(d *schema.ResourceData, config *Config) ([]*computeBeta.Attached
disk.DeviceName = v.(string)
}
if _, ok := d.GetOk(prefix + ".disk_encryption_key"); ok {
disk.DiskEncryptionKey = &computeBeta.CustomerEncryptionKey{}
if v, ok := d.GetOk(prefix + ".disk_encryption_key.0.kms_key_self_link"); ok {
disk.DiskEncryptionKey.KmsKeyName = v.(string)
}
}
if v, ok := d.GetOk(prefix + ".source"); ok {
disk.Source = v.(string)
} else {
@ -706,6 +730,14 @@ func flattenDisks(disks []*computeBeta.AttachedDisk, d *schema.ResourceData, def
diskMap["disk_name"] = disk.InitializeParams.DiskName
diskMap["disk_size_gb"] = disk.InitializeParams.DiskSizeGb
}
if disk.DiskEncryptionKey != nil {
encryption := make([]map[string]interface{}, 1)
encryption[0] = make(map[string]interface{})
encryption[0]["kms_key_self_link"] = disk.DiskEncryptionKey.KmsKeyName
diskMap["disk_encryption_key"] = encryption
}
diskMap["auto_delete"] = disk.AutoDelete
diskMap["boot"] = disk.Boot
diskMap["device_name"] = disk.DeviceName

View File

@ -472,6 +472,38 @@ func TestAccComputeInstanceTemplate_minCpuPlatform(t *testing.T) {
})
}
func TestAccComputeInstanceTemplate_EncryptKMS(t *testing.T) {
t.Parallel()
var instanceTemplate compute.InstanceTemplate
org := getTestOrgFromEnv(t)
pid := "tf-test-" + acctest.RandString(10)
billingAccount := getTestBillingAccountFromEnv(t)
diskName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
keyRingName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
keyName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeInstanceTemplate_encryptionKMS(pid, pname, org, billingAccount, diskName, keyRingName, keyName),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceTemplateExists("google_compute_instance_template.foobar", &instanceTemplate),
),
},
resource.TestStep{
ResourceName: "google_compute_instance_template.foobar",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccCheckComputeInstanceTemplateDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
@ -1390,3 +1422,87 @@ resource "google_compute_instance_template" "foobar" {
min_cpu_platform = "%s"
}`, i, DEFAULT_MIN_CPU_TEST_VALUE)
}
func testAccComputeInstanceTemplate_encryptionKMS(pid, pname, org, billing, diskName, keyRingName, keyName string) string {
return fmt.Sprintf(`
resource "google_project" "project" {
project_id = "%s"
name = "%s"
org_id = "%s"
billing_account = "%s"
}
data "google_compute_image" "my_image" {
family = "debian-9"
project = "debian-cloud"
}
resource "google_project_services" "apis" {
project = "${google_project.project.project_id}"
services = [
"oslogin.googleapis.com",
"compute.googleapis.com",
"cloudkms.googleapis.com",
"appengine.googleapis.com",
]
}
resource "google_project_iam_member" "kms-project-binding" {
project = "${google_project.project.project_id}"
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:service-${google_project.project.number}@compute-system.iam.gserviceaccount.com"
depends_on = ["google_project_services.apis"]
}
resource "google_kms_crypto_key_iam_binding" "kms-key-binding" {
crypto_key_id = "${google_kms_crypto_key.my_crypto_key.self_link}"
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
members = [
"serviceAccount:service-${google_project.project.number}@compute-system.iam.gserviceaccount.com",
]
depends_on = ["google_project_services.apis"]
}
resource "google_kms_key_ring" "my_key_ring" {
name = "%s"
project = "${google_project.project.project_id}"
location = "us-central1"
depends_on = ["google_project_services.apis"]
}
resource "google_kms_crypto_key" "my_crypto_key" {
name = "%s"
key_ring = "${google_kms_key_ring.my_key_ring.self_link}"
}
resource "google_compute_instance_template" "foobar" {
name = "instancet-test-%s"
machine_type = "n1-standard-1"
can_ip_forward = false
disk {
source_image = "${data.google_compute_image.my_image.self_link}"
disk_encryption_key {
kms_key_self_link = "${google_kms_crypto_key.my_crypto_key.self_link}"
}
}
network_interface {
network = "default"
}
service_account {
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
}
labels {
my_label = "foobar"
}
}`, pid, pname, org, billing, keyRingName, keyName, acctest.RandString(10))
}

View File

@ -286,6 +286,20 @@ The `disk` block supports:
* `type` - (Optional) The type of GCE disk, can be either `"SCRATCH"` or
`"PERSISTENT"`.
* `disk_encryption_key` - (Optional) Encrypts or decrypts a disk using a customer-supplied encryption key.
If you are creating a new disk, this field encrypts the new disk using an encryption key that you provide. If you are attaching an existing disk that is already encrypted, this field decrypts the disk using the customer-supplied encryption key.
If you encrypt a disk using a customer-supplied key, you must provide the same key again when you attempt to use this resource at a later time. For example, you must provide the key when you create a snapshot or an image from the disk or when you attach the disk to a virtual machine instance.
If you do not provide an encryption key, then the disk will be encrypted using an automatically generated key and you do not need to provide a key to use the disk later.
Instance templates do not store customer-supplied encryption keys, so you cannot use your own keys to encrypt disks in a managed instance group.
The `disk_encryption_key` block supports:
* `kms_key_self_link` - (Optional) The self link of the encryption key that is stored in Google Cloud KMS
The `network_interface` block supports:
* `network` - (Optional) The name or self_link of the network to attach this interface to.