Skip to content

Commit

Permalink
feat: Introduce autokey feature (#151)
Browse files Browse the repository at this point in the history
  • Loading branch information
romanini-ciandt authored Sep 17, 2024
1 parent eb71a31 commit f4471fd
Show file tree
Hide file tree
Showing 18 changed files with 512 additions and 10 deletions.
28 changes: 28 additions & 0 deletions examples/autokey_example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Autokey Example

This example illustrates how to use the `autokey` kms submodule for [KMS Autokey](https://cloud.google.com/kms/docs/autokey-overview) feature.

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

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| autokey\_resource\_project\_id | The ID of the project for Autokey to be used (e.g: a storage project which expects to use Autokey as CMEK). | `string` | n/a | yes |
| folder\_id | The Autokey folder number used by Autokey config resource. Required when using Autokey. | `string` | n/a | yes |
| project\_id | The ID of the project in which to provision Autokey resources (autokey keyring and keyHandle keys). | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| autokey\_config\_id | An Autokey configuration identifier. |
| autokey\_keyhandles | A map of KeyHandles created. |
| autokey\_project\_id | Project used for autokey. |

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

To provision this example, run the following from within this directory:
- `terraform init` to get the plugins
- `terraform plan` to see the infrastructure plan
- `terraform apply` to apply the infrastructure build
- `terraform destroy` to destroy the built infrastructure
43 changes: 43 additions & 0 deletions examples/autokey_example/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* 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 "autokey" {
source = "terraform-google-modules/kms/google//modules/autokey"

project_id = var.project_id
autokey_folder_number = var.folder_id
autokey_handles = {
storage_bucket = {
name = "bucket-key-handle",
project = var.autokey_resource_project_id,
resource_type_selector = "storage.googleapis.com/Bucket",
location = "us-central1"
}
compute_disk = {
name = "disk-key-handle",
project = var.autokey_resource_project_id,
resource_type_selector = "compute.googleapis.com/Disk",
location = "us-central1"
}
bigquery_dataset = {
name = "dataset-key-handle",
project = var.autokey_resource_project_id,
resource_type_selector = "bigquery.googleapis.com/Dataset",
location = "us-central1"
}
}
}

30 changes: 30 additions & 0 deletions examples/autokey_example/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* 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.
*/

output "autokey_config_id" {
description = "An Autokey configuration identifier."
value = module.autokey.autokey_config_id != null ? module.autokey.autokey_config_id : ""
}

output "autokey_keyhandles" {
description = "A map of KeyHandles created."
value = module.autokey.autokey_keyhandles != null ? module.autokey.autokey_keyhandles : {}
}

output "autokey_project_id" {
description = "Project used for autokey."
value = var.project_id
}
31 changes: 31 additions & 0 deletions examples/autokey_example/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* 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.
*/

variable "project_id" {
description = "The ID of the project in which to provision Autokey resources (autokey keyring and keyHandle keys)."
type = string
}

variable "autokey_resource_project_id" {
description = "The ID of the project for Autokey to be used (e.g: a storage project which expects to use Autokey as CMEK)."
type = string
}

variable "folder_id" {
type = string
description = "The Autokey folder number used by Autokey config resource. Required when using Autokey."
}

1 change: 0 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,3 @@ resource "google_kms_crypto_key_iam_binding" "encrypters" {
crypto_key_id = local.keys_by_name[element(var.set_encrypters_for, count.index)]
members = compact(split(",", var.encrypters[count.index]))
}

21 changes: 21 additions & 0 deletions modules/autokey/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Autokey submodule

This is a submodule built to make [KMS Autokey](https://cloud.google.com/kms/docs/autokey-overview) feature simple to be used. This submodule will create the [Autokey Config](https://cloud.google.com/kms/docs/enable-autokey#enable-autokey-folder) for an existing folder where you want to enable Autokey, set up the Cloud KMS [service agent](https://cloud.google.com/kms/docs/enable-autokey#autokey-service-agent) on an existing key project and create [Key Handles](https://cloud.google.com/kms/docs/resource-hierarchy#key_handles) for existing resource projects.

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

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| autokey\_folder\_number | The Autokey folder number used by Autokey config resource. Required when using Autokey. | `string` | n/a | yes |
| autokey\_handles | (Optional) A KeyHandle is a resource used by Autokey to auto-provision CryptoKeys for CMEK for a particular service.<br>- name: The resource name for the KeyHandle.<br>- resource\_type\_selector: Indicates the resource type that the resulting CryptoKey is meant to protect, in the following format: {SERVICE}.googleapis.com/{TYPE}. For example, storage.googleapis.com/Bucket. All Cloud KMS Autokey compatible services available at https://cloud.google.com/kms/docs/autokey-overview#compatible-services.<br>- location: The location for the KeyHandle. A full list of valid locations can be found by running gcloud kms locations list.<br>- project: The ID of the project in which the resource belongs. If it is not provided, the provider project is used. | <pre>map(object({<br> name = string<br> resource_type_selector = string<br> location = string<br> project = string<br> }))</pre> | `null` | no |
| project\_id | Project id where the Autokey configuration and KeyHandles will be created. | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| autokey\_config\_id | An Autokey configuration identifier. |
| autokey\_keyhandles | A map of KeyHandles created. |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
55 changes: 55 additions & 0 deletions modules/autokey/iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* 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.
*/

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

#Create KMS Service Agent
resource "google_project_service_identity" "kms_service_agent" {
count = local.create_autokey_key_handles ? 1 : 0
provider = google-beta

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

# Wait delay after creating service agent.
resource "time_sleep" "wait_service_agent" {
count = local.create_autokey_key_handles ? 1 : 0

create_duration = "10s"
depends_on = [google_project_service_identity.kms_service_agent]
}

#Grant the KMS Service Agent the Cloud KMS Admin role
resource "google_project_iam_member" "autokey_project_admin" {
count = local.create_autokey_key_handles ? 1 : 0
provider = google-beta

project = var.project_id
role = "roles/cloudkms.admin"
member = "serviceAccount:service-${data.google_project.kms_project.number}@gcp-sa-cloudkms.iam.gserviceaccount.com"
depends_on = [time_sleep.wait_service_agent]
}

# Wait delay after granting IAM permissions
resource "time_sleep" "wait_srv_acc_permissions" {
count = local.create_autokey_key_handles ? 1 : 0

create_duration = "10s"
depends_on = [google_project_iam_member.autokey_project_admin]
}
47 changes: 47 additions & 0 deletions modules/autokey/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* 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.
*/

locals {
create_autokey_key_handles = var.autokey_folder_number != null && var.autokey_handles != null
}

resource "google_kms_autokey_config" "primary" {
count = var.autokey_folder_number != null ? 1 : 0
provider = google-beta

folder = var.autokey_folder_number
key_project = "projects/${var.project_id}"
}

resource "random_string" "suffix" {
count = local.create_autokey_key_handles ? 1 : 0

length = 4
special = false
upper = false
}

resource "google_kms_key_handle" "primary" {
for_each = local.create_autokey_key_handles ? var.autokey_handles : tomap({})
provider = google-beta

project = each.value.project
name = "${each.value.name}-${random_string.suffix[0].result}"
location = each.value.location
resource_type_selector = each.value.resource_type_selector

depends_on = [time_sleep.wait_srv_acc_permissions]
}
25 changes: 25 additions & 0 deletions modules/autokey/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* 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.
*/

output "autokey_config_id" {
description = "An Autokey configuration identifier."
value = var.autokey_folder_number != null ? google_kms_autokey_config.primary[0].id : ""
}

output "autokey_keyhandles" {
description = "A map of KeyHandles created."
value = local.create_autokey_key_handles ? google_kms_key_handle.primary : {}
}
42 changes: 42 additions & 0 deletions modules/autokey/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* 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.
*/

variable "project_id" {
description = "Project id where the Autokey configuration and KeyHandles will be created."
type = string
}

variable "autokey_folder_number" {
type = string
description = "The Autokey folder number used by Autokey config resource. Required when using Autokey."
}

variable "autokey_handles" {
type = map(object({
name = string
resource_type_selector = string
location = string
project = string
}))
description = <<-EOF
(Optional) A KeyHandle is a resource used by Autokey to auto-provision CryptoKeys for CMEK for a particular service.
- name: The resource name for the KeyHandle.
- resource_type_selector: Indicates the resource type that the resulting CryptoKey is meant to protect, in the following format: {SERVICE}.googleapis.com/{TYPE}. For example, storage.googleapis.com/Bucket. All Cloud KMS Autokey compatible services available at https://cloud.google.com/kms/docs/autokey-overview#compatible-services.
- location: The location for the KeyHandle. A full list of valid locations can be found by running gcloud kms locations list.
- project: The ID of the project in which the resource belongs. If it is not provided, the provider project is used.
EOF
default = null
}
46 changes: 46 additions & 0 deletions modules/autokey/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* 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.
*/

terraform {
required_version = ">= 0.13"
required_providers {

google = {
source = "hashicorp/google"
version = ">= 5.31.0"
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 5.31.0"
}
time = {
source = "hashicorp/time"
version = ">= 0.12.0"
}
random = {
source = "hashicorp/random"
version = ">= 3.6.2"
}
}

provider_meta "google" {
module_name = "blueprints/terraform/terraform-google-kms:autokey/v3.0.0"
}
provider_meta "google-beta" {
module_name = "blueprints/terraform/terraform-google-kms:autokey/v3.0.0"
}

}
1 change: 0 additions & 1 deletion outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,3 @@ output "keyring_name" {
google_kms_crypto_key_iam_binding.encrypters,
]
}

Loading

0 comments on commit f4471fd

Please sign in to comment.