First commit

This commit is contained in:
lcaggio 2023-02-05 07:52:33 +01:00
parent 5241b2c4d3
commit 38fc9e8b9b
4 changed files with 86 additions and 62 deletions

View File

@ -1,8 +1,8 @@
# GCE and GCS CMEK via centralized Cloud KMS
This example creates a sample centralized [Cloud KMS](https://cloud.google.com/kms?hl=it) configuration, and uses it to implement CMEK for [Cloud Storage](https://cloud.google.com/storage/docs/encryption/using-customer-managed-keys) and [Compute Engine](https://cloud.google.com/compute/docs/disks/customer-managed-encryption) in a separate project.
This example creates a sample centralized [Cloud KMS](https://cloud.google.com/kms?hl=it) configuration, and uses it to implement CMEK for [Cloud Storage](https://cloud.google.com/storage/docs/encryption/using-customer-managed-keys) and [Compute Engine](https://cloud.google.com/compute/docs/disks/customer-managed-encryption) in a service project.
The example is designed to match real-world use cases with a minimum amount of resources, and be used as a starting point for scenarios where application projects implement CMEK using keys managed by a central team. It also includes the IAM wiring needed to make such scenarios work.
The example is designed to match real-world use cases with a minimum amount of resources, and be used as a starting point for scenarios where application projects implement CMEK using keys managed by a central team. It also includes the IAM wiring needed to make such scenarios work. Regional resources are used in this example, but the same logic will apply for 'dual regional', 'multi regional' or 'global' resources.
This is the high level diagram:
@ -35,12 +35,11 @@ This sample creates several distinct groups of resources:
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [billing_account](variables.tf#L16) | Billing account id used as default for new projects. | <code>string</code> | ✓ | |
| [root_node](variables.tf#L45) | The resource name of the parent Folder or Organization. Must be of the form folders/folder_id or organizations/org_id. | <code>string</code> | ✓ | |
| [location](variables.tf#L21) | The location where resources will be deployed. | <code>string</code> | | <code>&#34;europe&#34;</code> |
| [project_kms_name](variables.tf#L27) | Name for the new KMS Project. | <code>string</code> | | <code>&#34;my-project-kms-001&#34;</code> |
| [project_service_name](variables.tf#L33) | Name for the new Service Project. | <code>string</code> | | <code>&#34;my-project-service-001&#34;</code> |
| [region](variables.tf#L39) | The region where resources will be deployed. | <code>string</code> | | <code>&#34;europe-west1&#34;</code> |
| [prefix](variables.tf#L21) | Optional prefix used to generate resources names. | <code>string</code> | ✓ | |
| [project_ids](variables.tf#L36) | Project ids, references existing project if `project_create` is null. | <code title="object&#40;&#123;&#10; encryption &#61; string&#10; service &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [location](variables.tf#L15) | The location where resources will be deployed. | <code>string</code> | | <code>&#34;europe&#34;</code> |
| [project_create](variables.tf#L27) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object&#40;&#123;&#10; billing_account_id &#61; string&#10; parent &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [region](variables.tf#L44) | The region where resources will be deployed. | <code>string</code> | | <code>&#34;europe-west1&#34;</code> |
| [vpc_ip_cidr_range](variables.tf#L50) | Ip range used in the subnet deployef in the Service Project. | <code>string</code> | | <code>&#34;10.0.0.0&#47;20&#34;</code> |
| [vpc_name](variables.tf#L56) | Name of the VPC created in the Service Project. | <code>string</code> | | <code>&#34;local&#34;</code> |
| [vpc_subnet_name](variables.tf#L62) | Name of the subnet created in the Service Project. | <code>string</code> | | <code>&#34;subnet&#34;</code> |

View File

@ -12,33 +12,61 @@
# See the License for the specific language governing permissions and
# limitations under the License.
locals {
# Needed when you create KMS keys and encrypted resources in the same terraform state but different projects.
kms_keys = {
gce = "projects/${module.project-kms.project_id}/locations/${var.region}/keyRings/${var.region}/cryptoKeys/key-gcs"
gcs = "projects/${module.project-kms.project_id}/locations/${var.region}/keyRings/${var.region}/cryptoKeys/key-gcs"
}
}
###############################################################################
# Projects #
###############################################################################
module "project-service" {
source = "../../../modules/project"
name = var.project_service_name
parent = var.root_node
billing_account = var.billing_account
name = var.project_ids.service
parent = try(var.project_create.parent, null)
billing_account = try(var.project_create.billing_account_id, null)
project_create = var.project_create != null
prefix = var.project_create == null ? null : var.prefix
services = [
"compute.googleapis.com",
"servicenetworking.googleapis.com",
"storage-component.googleapis.com"
"storage.googleapis.com",
"storage-component.googleapis.com",
]
service_encryption_key_ids = {
compute = [
local.kms_keys.gce
]
storage = [
local.kms_keys.gcs
]
}
service_config = {
disable_on_destroy = false, disable_dependent_services = false
}
depends_on = [
module.kms
]
oslogin = true
}
module "project-kms" {
source = "../../../modules/project"
name = var.project_kms_name
parent = var.root_node
billing_account = var.billing_account
name = var.project_ids.encryption
parent = try(var.project_create.parent, null)
billing_account = try(var.project_create.billing_account_id, null)
project_create = var.project_create != null
prefix = var.project_create == null ? null : var.prefix
services = [
"cloudkms.googleapis.com",
"servicenetworking.googleapis.com"
]
oslogin = true
service_config = {
disable_on_destroy = false, disable_dependent_services = false
}
}
###############################################################################
@ -48,11 +76,11 @@ module "project-kms" {
module "vpc" {
source = "../../../modules/net-vpc"
project_id = module.project-service.project_id
name = var.vpc_name
name = "${var.prefix}-vpc"
subnets = [
{
ip_cidr_range = var.vpc_ip_cidr_range
name = var.vpc_subnet_name
ip_cidr_range = "10.0.0.0/20"
name = "${var.prefix}-${var.region}"
region = var.region
}
]
@ -63,7 +91,7 @@ module "vpc-firewall" {
project_id = module.project-service.project_id
network = module.vpc.name
default_rules_config = {
admin_ranges = [var.vpc_ip_cidr_range]
admin_ranges = ["10.0.0.0/20"]
}
}
@ -75,22 +103,10 @@ module "kms" {
source = "../../../modules/kms"
project_id = module.project-kms.project_id
keyring = {
name = "my-keyring",
location = var.location
name = var.region,
location = var.region
}
keys = { key-gce = null, key-gcs = null }
key_iam = {
key-gce = {
"roles/cloudkms.cryptoKeyEncrypterDecrypter" = [
"serviceAccount:${module.project-service.service_accounts.robots.compute}",
]
},
key-gcs = {
"roles/cloudkms.cryptoKeyEncrypterDecrypter" = [
"serviceAccount:${module.project-service.service_accounts.robots.storage}",
]
}
}
}
###############################################################################
@ -101,10 +117,10 @@ module "vm_example" {
source = "../../../modules/compute-vm"
project_id = module.project-service.project_id
zone = "${var.region}-b"
name = "kms-vm"
name = "${var.prefix}-vm"
network_interfaces = [{
network = module.vpc.self_link,
subnetwork = module.vpc.subnet_self_links["${var.region}/subnet"],
subnetwork = module.vpc.subnet_self_links["${var.region}/${var.prefix}-${var.region}"],
nat = false,
addresses = null
}]
@ -127,7 +143,7 @@ module "vm_example" {
encryption = {
encrypt_boot = true
disk_encryption_key_raw = null
kms_key_self_link = module.kms.key_ids.key-gce
kms_key_self_link = local.kms_keys.gce
}
}
@ -138,7 +154,9 @@ module "vm_example" {
module "kms-gcs" {
source = "../../../modules/gcs"
project_id = module.project-service.project_id
prefix = "my-bucket-001"
name = "kms-gcs"
encryption_key = module.kms.keys.key-gcs.id
prefix = var.prefix
name = "${var.prefix}-bucket"
location = var.region
storage_class = "REGIONAL"
encryption_key = local.kms_keys.gcs
}

View File

@ -12,28 +12,33 @@
# See the License for the specific language governing permissions and
# limitations under the License.
variable "billing_account" {
description = "Billing account id used as default for new projects."
type = string
}
variable "location" {
description = "The location where resources will be deployed."
type = string
default = "europe"
}
variable "project_kms_name" {
description = "Name for the new KMS Project."
variable "prefix" {
description = "Optional prefix used to generate resources names."
type = string
default = "my-project-kms-001"
nullable = false
}
variable "project_service_name" {
description = "Name for the new Service Project."
type = string
default = "my-project-service-001"
variable "project_create" {
description = "Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format."
type = object({
billing_account_id = string
parent = string
})
default = null
}
variable "project_ids" {
description = "Project ids, references existing project if `project_create` is null."
type = object({
encryption = string
service = string
})
}
variable "region" {
@ -42,11 +47,6 @@ variable "region" {
default = "europe-west1"
}
variable "root_node" {
description = "The resource name of the parent Folder or Organization. Must be of the form folders/folder_id or organizations/org_id."
type = string
}
variable "vpc_ip_cidr_range" {
description = "Ip range used in the subnet deployef in the Service Project."
type = string

View File

@ -15,7 +15,14 @@
*/
module "test" {
source = "../../../../../blueprints/data-solutions/cmek-via-centralized-kms/"
billing_account = var.billing_account
root_node = var.root_node
source = "../../../../../blueprints/data-solutions/cmek-via-centralized-kms/"
project_create = {
billing_account_id = "123456-123456-123456"
parent = "folders/12345678"
}
project_ids = {
encryption = "kms"
service = "service"
}
prefix = "prefix"
}