Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update KMS blueprint #1129

Merged
merged 2 commits into from
Feb 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions blueprints/data-solutions/cmek-via-centralized-kms/README.md
Original file line number Diff line number Diff line change
@@ -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:

Expand Down Expand Up @@ -35,12 +35,10 @@ 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_config](variables.tf#L27) | Provide 'billing_account_id' and 'parent' values if project creation is needed, uses existing 'projects_id' if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object&#40;&#123;&#10; billing_account_id &#61; optional&#40;string, null&#41;&#10; parent &#61; optional&#40;string, null&#41;&#10; project_ids &#61; optional&#40;object&#40;&#123;&#10; encryption &#61; string&#10; service &#61; string&#10; &#125;&#41;, &#123;&#10; encryption &#61; &#34;encryption&#34;,&#10; service &#61; &#34;service&#34;&#10; &#125;&#10; &#41;&#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> |
| [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> |
Expand Down
84 changes: 51 additions & 33 deletions blueprints/data-solutions/cmek-via-centralized-kms/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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.prefix}-${var.region}/cryptoKeys/key-gcs"
gcs = "projects/${module.project-kms.project_id}/locations/${var.region}/keyRings/${var.prefix}-${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_config.project_ids.service
parent = var.project_config.parent
billing_account = var.project_config.billing_account_id
project_create = var.project_config.billing_account_id != null
prefix = var.project_config.billing_account_id == 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_config.project_ids.encryption
parent = var.project_config.parent
billing_account = var.project_config.billing_account_id
project_create = var.project_config.billing_account_id != null
prefix = var.project_config.billing_account_id == null ? null : var.prefix
services = [
"cloudkms.googleapis.com",
"servicenetworking.googleapis.com"
]
oslogin = true
service_config = {
disable_on_destroy = false, disable_dependent_services = false
}
}

###############################################################################
Expand All @@ -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
}
]
Expand All @@ -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"]
}
}

Expand All @@ -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.prefix}-${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}",
]
}
}
}

###############################################################################
Expand All @@ -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
}]
Expand All @@ -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
}
}

Expand All @@ -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
}
36 changes: 18 additions & 18 deletions blueprints/data-solutions/cmek-via-centralized-kms/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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_config" {
description = "Provide 'billing_account_id' and 'parent' values if project creation is needed, uses existing 'projects_id' if null. Parent is in 'folders/nnn' or 'organizations/nnn' format."
type = object({
billing_account_id = optional(string, null)
parent = optional(string, null)
project_ids = optional(object({
encryption = string
service = string
}), {
encryption = "encryption",
service = "service"
}
)
})
nullable = false
}

variable "region" {
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
*/

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_config = {
billing_account_id = "123456-123456-123456"
parent = "folders/12345678"
}
prefix = "prefix"
}

This file was deleted.