Skip to content

Commit

Permalink
Merge branch 'main' of github.com:romanini-ciandt/kms-solutions into …
Browse files Browse the repository at this point in the history
…feat/pkcs11-automations
  • Loading branch information
romanini-ciandt committed Apr 30, 2024
2 parents 4db9fba + d4462b9 commit 974d47a
Show file tree
Hide file tree
Showing 23 changed files with 909 additions and 53 deletions.
86 changes: 86 additions & 0 deletions ekm-over-vpc-onboarding/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# KMS EKM connection over a VPC onboarding

## Overview

This guide provides instructions of an automation for Cloud External Key Manager (Cloud EKM) to connect to your external key management (EKM) provider over a Virtual Private Cloud (VPC) network with Terraform.

## Prerequisites

- [Terraform](https://developer.hashicorp.com/terraform/downloads) >= 1.5.7;
- [Google Cloud CLI (`gcloud`)](https://cloud.google.com/sdk/docs/install-sdk);
- You must be authenticated in your GCP account. If you're not, you should run `gcloud auth login`;
- Some IAM permissions will be granted to the authenticated user by this terraform automation. If you want to grant to other user instead, fulfill `project_creator_member_email` in your `terraform.tfvars` file.
- An existing [GCP Organization](https://cloud.google.com/resource-manager/docs/creating-managing-organization);
- [Project Creator role](https://cloud.google.com/resource-manager/docs/default-access-control#adding_a_billing_account_creator_and_project_creator) in the GCP Organization for the authenticated user;
- (Optional) An existing [GCP project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project) to create all the VPC related resources;
- (Optional) An existing [GCP project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project) to create all the KMS related resources;

**Note:** VPC and KMS projects are optional because this terraform automation can auto-create them for you. All you need to do is to set `create_kms_project` and `create_vpc_project` to `true` in your `terraform.tfvars` file.
- If you would like terraform to create kms and vpc projects, please provide account user (the one you used for `gcloud auth login`) with "roles/resourcemanager.projectCreator" iam role.

**Note 2:** Your EKM provider should be placed/referenced in your VPC project. A Private IP address of the EKM or an IP address for the load balancer pointing to the EKM is required in your `terraform.tfvars` file. You will need to edit `modules/create_ekm_resources/network.tf` file for any forwarding-rule resources you would like to add

## Deploy infrastructure

1. Rename `terraform.example.tfvars` to `terraform.tfvars`:
```sh
mv terraform.example.tfvars terraform.tfvars
```

1. Update `terraform.tfvars` file with the required values.

1. Create the infrastructure.

```sh
terraform init
terraform plan
terraform apply
```

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| billing\_account | Billing Account for the customer | `string` | `""` | no |
| create\_kms\_project | If true, a project for KMS will be created automatically | `bool` | `true` | no |
| create\_vpc\_project | If true, a project for VPC will be created automatically | `bool` | `true` | no |
| crypto\_space\_path | External key provider crypto space path (ie. v0/longlived/a1-example) | `string` | `""` | no |
| ekm\_connection\_key\_path | Each Cloud EKM key version contains either a key URI or a key path. This is a unique identifier for the external key material that Cloud EKM uses when requesting cryptographic operations using the key. When key\_management\_mode is CLOUD\_KMS, this variable will be equals to crypto\_space\_path | `string` | n/a | yes |
| ekmconnection\_name | Name of the ekmconnection resource | `string` | `"ekmconnection"` | no |
| external\_key\_manager\_ip | Private IP address of the external key manager or ip address for the load balancer pointing to the external key manager | `string` | `"10.2.0.48"` | no |
| external\_key\_manager\_port | Port of the external key manager or port for the load balancer pointing to the external key manager | `string` | `"443"` | no |
| external\_provider\_hostname | Hostname for external key manager provider (ie. private-ekm.example.endpoints.cloud.goog) | `string` | n/a | yes |
| external\_provider\_raw\_der | External key provider server certificate in base64 format | `string` | n/a | yes |
| folder\_id | (Optional) The ID of the GCP folder to create the projects | `string` | `""` | no |
| key\_management\_mode | Key management mode. Possible values: MANUAL and CLOUD\_KMS. Defaults to MANUAL | `string` | `"MANUAL"` | no |
| kms\_name\_prefix | Key management resources name prefix | `string` | `"kms-vpc"` | no |
| kms\_project\_id | ID of the KMS project you would like to create | `string` | `""` | no |
| kms\_project\_name | Name of the KMS project you would like to create | `string` | n/a | yes |
| location | Location where resources will be created | `string` | `"us-central1"` | no |
| network\_name | Name of the Network resource | `string` | `"vpc-network-name"` | no |
| organization\_id | The ID of the existing GCP organization | `string` | n/a | yes |
| project\_creator\_member\_email | Email of the user that will be granted permissions to create resources under the projects | `string` | `""` | no |
| random\_project\_suffix | If true, a suffix of 4 random characters will be appended to project names. Only applies when create project flag is true. | `bool` | `false` | no |
| servicedirectory\_name | Service Directory resource name | `string` | `"ekm-service-directory"` | no |
| subnet\_ip\_cidr\_range | ip\_cidr\_range for subnet resource | `string` | `"10.2.0.0/16"` | no |
| vpc\_project\_id | ID of the VPC project, default to same as KMS | `string` | `""` | no |
| vpc\_project\_name | Name of the VPC project, default to same as KMS | `string` | `""` | no |

## Outputs

| Name | Description |
|------|-------------|
| crypto\_key | Name of the crypto key created. |
| ekm\_connection\_id | ID of the EKM connection created. |
| key\_version | Name of the key version created. |
| keyring | Name of the keyring. |
| kms\_project\_id | ID of the KMS project |
| location | Location of the keyring created. |
| vpc\_project\_id | ID of the VPC project |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

**Note 3:** You will need to manually set crypto-key-version to `primary version` by either using Google console or [Google CLI command](https://cloud.google.com/sdk/gcloud/reference/kms/keys/set-primary-version).

Congrats! You have successfully created all your required resources to use EKM over VPC
53 changes: 53 additions & 0 deletions ekm-over-vpc-onboarding/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

module "create_vpc_kms_project" {
source = "./modules/create_vpc_kms_project"

organization_id = var.organization_id
folder_id = var.folder_id
kms_project_name = var.kms_project_name
kms_project_id = var.kms_project_id
vpc_project_name = var.vpc_project_name
vpc_project_id = var.vpc_project_id
billing_account = var.billing_account
create_kms_project = var.create_kms_project
create_vpc_project = var.create_vpc_project
random_project_suffix = var.random_project_suffix
}

module "ekm_resources" {
source = "./modules/ekm_resources_creation"

kms_project_id = module.create_vpc_kms_project.kms_project_id
vpc_project_id = module.create_vpc_kms_project.vpc_project_id
location = var.location
subnet_ip_cidr_range = var.subnet_ip_cidr_range
external_key_manager_ip = var.external_key_manager_ip
external_key_manager_port = var.external_key_manager_port
external_provider_hostname = var.external_provider_hostname
external_provider_raw_der = var.external_provider_raw_der
crypto_space_path = var.crypto_space_path
network_name = var.network_name
servicedirectory_name = var.servicedirectory_name
kms_name_prefix = var.kms_name_prefix
ekmconnection_name = var.ekmconnection_name
key_management_mode = var.key_management_mode
project_creator_member_email = var.project_creator_member_email
ekm_connection_key_path = var.ekm_connection_key_path

depends_on = [module.create_vpc_kms_project]
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ This module provides the project infrastructure setup (creation and/or API servi
| kms\_project\_id | ID of the KMS project you would like to create | `string` | `""` | no |
| kms\_project\_name | Name of the KMS project you would like to create | `string` | n/a | yes |
| organization\_id | The ID of the existing GCP organization | `string` | n/a | yes |
| project\_creator\_member\_email | Email of the user that will be granted permissions to create resources under the projects | `string` | `""` | no |
| random\_project\_suffix | If true, a suffix of 4 random characters will be appended to project names. Only applies when create project flag is true. | `bool` | `false` | no |
| vpc\_project\_id | ID of the VPC project, default to same as KMS | `string` | `""` | no |
| vpc\_project\_name | Name of the VPC project, default to same as KMS | `string` | `""` | no |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,6 @@ locals {

}

# User Credentials (Default: Current logged in user)
data "google_client_openid_userinfo" "provider_identity" {
}

# Add permission to create projects
resource "google_organization_iam_member" "project_create_iam_member" {
org_id = var.organization_id
role = "roles/resourcemanager.projectCreator"
member = format("user:%s", var.project_creator_member_email == "" ? data.google_client_openid_userinfo.provider_identity.email : var.project_creator_member_email)
}

# Create KMS and VPC projects if specified
module "kms_project" {
count = var.create_kms_project ? 1 : 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,6 @@ variable "billing_account" {
description = "Billing Account for the customer"
}

variable "project_creator_member_email" {
type = string
default = ""
nullable = true
description = "Email of the user that will be granted permissions to create resources under the projects"
}

variable "folder_id" {
type = string
default = ""
Expand Down
39 changes: 39 additions & 0 deletions ekm-over-vpc-onboarding/modules/ekm_resources_creation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# EKM resources creation module

## Overview

This module provides all the EKM infrastructure creation (EKM connection, key, keyring) sample with Terraform.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| crypto\_space\_path | External key provider crypto space path (ie. v0/longlived/a1-example) | `string` | `""` | no |
| ekm\_connection\_key\_path | Each Cloud EKM key version contains either a key URI or a key path. This is a unique identifier for the external key material that Cloud EKM uses when requesting cryptographic operations using the key. When key\_management\_mode is CLOUD\_KMS, this variable will be equals to crypto\_space\_path | `string` | n/a | yes |
| ekmconnection\_name | Name of the ekmconnection resource | `string` | `"ekmconnection"` | no |
| external\_key\_manager\_ip | Private IP address of the external key manager or ip address for the load balancer pointing to the external key manager | `string` | `"10.2.0.48"` | no |
| external\_key\_manager\_port | Port of the external key manager or port for the load balancer pointing to the external key manager | `string` | `"443"` | no |
| external\_provider\_hostname | Hostname for external key manager provider (ie. private-ekm.example.endpoints.cloud.goog) | `string` | n/a | yes |
| external\_provider\_raw\_der | External key provider server certificate in base64 format | `string` | n/a | yes |
| key\_management\_mode | Key management mode. Possible values: MANUAL and CLOUD\_KMS. Defaults to MANUAL | `string` | `"MANUAL"` | no |
| kms\_name\_prefix | Key management resources name prefix | `string` | `"kms-vpc"` | no |
| kms\_project\_id | ID of the KMS project you would like to create | `string` | n/a | yes |
| location | Location where resources will be created | `string` | `"us-central1"` | no |
| network\_name | Name of the Network resource | `string` | `"vpc-network-name"` | no |
| project\_creator\_member\_email | Email of the user that will be granted permissions to create resources under the projects | `string` | `""` | no |
| servicedirectory\_name | Service Directory resource name | `string` | `"ekm-service-directory"` | no |
| subnet\_ip\_cidr\_range | ip\_cidr\_range for subnet resource | `string` | `"10.2.0.0/16"` | no |
| vpc\_project\_id | ID of the VPC project, default to same as KMS | `string` | `""` | no |

## Outputs

| Name | Description |
|------|-------------|
| crypto\_key | Name of the crypto key created. |
| ekm\_connection\_id | ID of the EKM connection created. |
| key\_version | Name of the key version created. |
| keyring | Name of the keyring. |
| location | Location of the keyring created. |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
49 changes: 49 additions & 0 deletions ekm-over-vpc-onboarding/modules/ekm_resources_creation/iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

# Grants appropriate permissions to the projects
resource "google_project_iam_member" "iam_member_roles_kms" {
for_each = toset([
"roles/cloudkms.admin"
])
role = each.key
member = format("user:%s", var.project_creator_member_email == "" ? data.google_client_openid_userinfo.provider_identity.email : var.project_creator_member_email)
project = data.google_project.kms_project.number
}
resource "google_project_iam_member" "iam_member_roles_vpc" {
for_each = toset([
"roles/compute.networkAdmin",
"roles/compute.securityAdmin",
"roles/servicedirectory.admin",
])
role = each.key
member = format("user:%s", var.project_creator_member_email == "" ? data.google_client_openid_userinfo.provider_identity.email : var.project_creator_member_email)
project = data.google_project.vpc_project.number
}

#Granting appropriate roles to service account
resource "google_project_iam_member" "sd_iam_member_roles" {
for_each = toset([
"roles/servicedirectory.pscAuthorizedService",
"roles/servicedirectory.viewer",
"roles/servicedirectory.networkAttacher",
])
role = each.key
member = "serviceAccount:service-${data.google_project.kms_project.number}@gcp-sa-ekms.iam.gserviceaccount.com"
project = data.google_project.vpc_project.number

depends_on = [google_project_service_identity.enable_ekm_service_agent]
}
83 changes: 83 additions & 0 deletions ekm-over-vpc-onboarding/modules/ekm_resources_creation/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


#####
# Script to create resources
#####

data "google_project" "kms_project" {
project_id = var.kms_project_id
}

data "google_project" "vpc_project" {
project_id = var.vpc_project_id == "" ? var.kms_project_id : var.vpc_project_id
}

# User Credentials (Default: Current logged in user)
data "google_client_openid_userinfo" "provider_identity" {
}

resource "google_project_service_identity" "enable_ekm_service_agent" {
provider = google-beta

project = data.google_project.kms_project.number
service = "cloudkms.googleapis.com"
}

#EKM Connection Creation
resource "google_kms_ekm_connection" "ekm_main_resource" {
name = var.ekmconnection_name
location = var.location
key_management_mode = var.key_management_mode
project = var.kms_project_id
service_resolvers {
service_directory_service = google_service_directory_service.sd_service.id
hostname = var.external_provider_hostname
server_certificates {
raw_der = var.external_provider_raw_der
}
}
crypto_space_path = var.crypto_space_path
}

# #Key Ring Creation
resource "google_kms_key_ring" "vpc_kms_ring" {
name = "${var.kms_name_prefix}-keyring"
location = var.location
project = var.kms_project_id
}

# #Key Creation
resource "google_kms_crypto_key" "vpc_key" {
name = "${var.kms_name_prefix}-key"
key_ring = google_kms_key_ring.vpc_kms_ring.id
purpose = "ENCRYPT_DECRYPT"

version_template {
algorithm = "EXTERNAL_SYMMETRIC_ENCRYPTION"
protection_level = "EXTERNAL_VPC"
}
skip_initial_version_creation = true
crypto_key_backend = google_kms_ekm_connection.ekm_main_resource.id
depends_on = [google_service_directory_service.sd_service]
}
resource "google_kms_crypto_key_version" "vpc_crypto_key_version" {
crypto_key = google_kms_crypto_key.vpc_key.id
external_protection_level_options {
ekm_connection_key_path = var.ekm_connection_key_path
}
}
Loading

0 comments on commit 974d47a

Please sign in to comment.