Skip to content
Open
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
24 changes: 24 additions & 0 deletions examples/simple_bucket_autokey/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Simple Example

This example illustrates how to use the `simple-bucket` submodule.

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

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| folder\_id | The folder where project is created | `string` | n/a | yes |
| key\_project\_id | The project where autokey is setup | `string` | n/a | yes |
| project\_id | The ID of the project in which to provision resources. | `string` | n/a | yes |

## Outputs

No outputs.

<!-- 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
74 changes: 74 additions & 0 deletions examples/simple_bucket_autokey/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* Copyright 2020 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 "bucket" {
source = "terraform-google-modules/cloud-storage/google//modules/simple_bucket"
version = "~> 9.0"

name = "${var.project_id}-bucket"
project_id = var.project_id
location = "us"

website = {
main_page_suffix = "index.html"
not_found_page = "404.html"
}

cors = [{
origin = ["http://image-store.com"]
method = ["GET", "HEAD", "PUT", "POST", "DELETE"]
response_header = ["*"]
max_age_seconds = 3600
}]

lifecycle_rules = [{
action = {
type = "Delete"
}
condition = {
age = 365
with_state = "ANY"
matches_prefix = var.project_id
}
}]

custom_placement_config = {
data_locations : ["US-EAST4", "US-WEST1"]
}

iam_members = [{
role = "roles/storage.objectViewer"
member = "group:[email protected]"
}]

autoclass = true
internal_encryption_config = {
create_encryption_key = true
use_autokey = true
}
depends_on = [time_sleep.wait_autokey_config]
}

resource "google_kms_autokey_config" "autokey_config" {
provider = google-beta
folder = var.folder_id
key_project = "projects/${var.key_project_id}"
}

resource "time_sleep" "wait_autokey_config" {
create_duration = "10s"
depends_on = [google_kms_autokey_config.autokey_config]
}
30 changes: 30 additions & 0 deletions examples/simple_bucket_autokey/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright 2018 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 resources."
type = string
}

variable "key_project_id" {
type = string
description = "The project where autokey is setup"
}

variable "folder_id" {
type = string
description = "The folder where project is created"
}
24 changes: 24 additions & 0 deletions examples/simple_bucket_autokey/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright 2019 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"
}
}
}
2 changes: 1 addition & 1 deletion modules/simple_bucket/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Functional examples are included in the
| encryption | A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/<project-name>/locations/<location-name>/keyRings/<keyring-name>/cryptoKeys/<key-name>`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable. | <pre>object({<br> default_kms_key_name = string<br> })</pre> | `null` | no |
| force\_destroy | When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects. | `bool` | `false` | no |
| iam\_members | The list of IAM members to grant permissions on the bucket. | <pre>list(object({<br> role = string<br> member = string<br> }))</pre> | `[]` | no |
| internal\_encryption\_config | Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket<br> instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.<br> create\_encryption\_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created<br> prevent\_destroy: Set the prevent\_destroy lifecycle attribute on keys.<br> key\_destroy\_scheduled\_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.<br> key\_rotation\_period: Generate a new key every time this period passes. | <pre>object({<br> create_encryption_key = optional(bool, false)<br> prevent_destroy = optional(bool, false)<br> key_destroy_scheduled_duration = optional(string, null)<br> key_rotation_period = optional(string, "7776000s")<br> })</pre> | `{}` | no |
| internal\_encryption\_config | Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket<br> instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.<br> create\_encryption\_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created.<br> use\_autokey: If `true`, KMS key is created in configured autokey project automatically and used as default encryption key.<br> prevent\_destroy: Set the prevent\_destroy lifecycle attribute on keys.<br> key\_destroy\_scheduled\_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.<br> key\_rotation\_period: Generate a new key every time this period passes. | <pre>object({<br> create_encryption_key = optional(bool, false)<br> use_autokey = optional(bool, false)<br> prevent_destroy = optional(bool, false)<br> key_destroy_scheduled_duration = optional(string, null)<br> key_rotation_period = optional(string, "7776000s")<br> })</pre> | `{}` | no |
| labels | A set of key/value label pairs to assign to the bucket. | `map(string)` | `null` | no |
| lifecycle\_rules | The bucket's Lifecycle Rules configuration. | <pre>list(object({<br> # Object with keys:<br> # - type - The type of the action of this Lifecycle Rule. Supported values: Delete and SetStorageClass.<br> # - storage_class - (Required if action type is SetStorageClass) The target Storage Class of objects affected by this Lifecycle Rule.<br> action = object({<br> type = string<br> storage_class = optional(string)<br> })<br><br> # Object with keys:<br> # - age - (Optional) Minimum age of an object in days to satisfy this condition.<br> # - send_age_if_zero - (Optional) While set true, num_newer_versions value will be sent in the request even for zero value of the field.<br> # - created_before - (Optional) Creation date of an object in RFC 3339 (e.g. 2017-06-13) to satisfy this condition.<br> # - with_state - (Optional) Match to live and/or archived objects. Supported values include: "LIVE", "ARCHIVED", "ANY".<br> # - matches_storage_class - (Optional) Storage Class of objects to satisfy this condition. Supported values include: MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, STANDARD, DURABLE_REDUCED_AVAILABILITY.<br> # - matches_prefix - (Optional) One or more matching name prefixes to satisfy this condition.<br> # - matches_suffix - (Optional) One or more matching name suffixes to satisfy this condition<br> # - num_newer_versions - (Optional) Relevant only for versioned objects. The number of newer versions of an object to satisfy this condition.<br> # - custom_time_before - (Optional) A date in the RFC 3339 format YYYY-MM-DD. This condition is satisfied when the customTime metadata for the object is set to an earlier date than the date used in this lifecycle condition.<br> # - days_since_custom_time - (Optional) Days since the date set in the customTime metadata for the object.<br> # - days_since_noncurrent_time - (Optional) Relevant only for versioned objects. Number of days elapsed since the noncurrent timestamp of an object.<br> # - noncurrent_time_before - (Optional) Relevant only for versioned objects. The date in RFC 3339 (e.g. 2017-06-13) when the object became nonconcurrent.<br> condition = object({<br> age = optional(number)<br> send_age_if_zero = optional(bool)<br> created_before = optional(string)<br> with_state = optional(string)<br> matches_storage_class = optional(string)<br> matches_prefix = optional(string)<br> matches_suffix = optional(string)<br> num_newer_versions = optional(number)<br> custom_time_before = optional(string)<br> days_since_custom_time = optional(number)<br> days_since_noncurrent_time = optional(number)<br> noncurrent_time_before = optional(string)<br> })<br> }))</pre> | `[]` | no |
| location | The location of the bucket. See https://cloud.google.com/storage/docs/locations. | `string` | n/a | yes |
Expand Down
13 changes: 11 additions & 2 deletions modules/simple_bucket/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

locals {
internal_encryption = var.internal_encryption_config.create_encryption_key ? { default_kms_key_name = module.encryption_key[0].keys[var.name] } : null
internal_encryption = var.internal_encryption_config.create_encryption_key ? var.internal_encryption_config.use_autokey ? { default_kms_key_name = google_kms_key_handle.default[0].kms_key } : { default_kms_key_name = module.encryption_key[0].keys[var.name] } : null
encryption = var.internal_encryption_config.create_encryption_key ? local.internal_encryption : var.encryption
}

Expand Down Expand Up @@ -117,6 +117,15 @@ resource "google_storage_bucket" "bucket" {
}
}

resource "google_kms_key_handle" "default" {
count = var.internal_encryption_config.create_encryption_key ? var.internal_encryption_config.use_autokey ? 1 : 0 : 0
provider = google-beta
project = var.project_id
name = var.name
location = var.location
resource_type_selector = "storage.googleapis.com/Bucket"
}

resource "google_storage_bucket_iam_member" "members" {
for_each = {
for m in var.iam_members : "${m.role} ${m.member}" => m
Expand All @@ -133,7 +142,7 @@ data "google_storage_project_service_account" "gcs_account" {
module "encryption_key" {
source = "terraform-google-modules/kms/google"
version = "~> 4.0"
count = var.internal_encryption_config.create_encryption_key ? 1 : 0
count = var.internal_encryption_config.create_encryption_key ? var.internal_encryption_config.use_autokey ? 0 : 1 : 0

project_id = var.project_id
location = lower(var.location)
Expand Down
2 changes: 1 addition & 1 deletion modules/simple_bucket/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ output "url" {

output "internal_kms_configuration" {
description = "The intenal KMS Resource."
value = var.internal_encryption_config.create_encryption_key ? module.encryption_key[0] : null
value = var.internal_encryption_config.create_encryption_key ? var.internal_encryption_config.use_autokey ? google_kms_key_handle.default[0] : module.encryption_key[0] : null
}

output "apphub_service_uri" {
Expand Down
4 changes: 3 additions & 1 deletion modules/simple_bucket/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,15 @@ variable "internal_encryption_config" {
description = <<EOT
Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket
instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.
create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created
create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created.
use_autokey: If `true`, KMS key is created in configured autokey project automatically and used as default encryption key.
prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.
key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.
key_rotation_period: Generate a new key every time this period passes.
EOT
type = object({
create_encryption_key = optional(bool, false)
use_autokey = optional(bool, false)
prevent_destroy = optional(bool, false)
key_destroy_scheduled_duration = optional(string, null)
key_rotation_period = optional(string, "7776000s")
Expand Down
2 changes: 2 additions & 0 deletions test/setup/iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

locals {
int_required_roles = [
"roles/cloudkms.admin",
"roles/cloudkms.autokeyAdmin",
"roles/cloudkms.cryptoKeyEncrypterDecrypter",
"roles/iam.serviceAccountUser",
"roles/storage.admin",
Expand Down
53 changes: 53 additions & 0 deletions test/setup/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,56 @@ module "project" {
"storage-api.googleapis.com",
]
}

resource "google_folder" "autokey_folder" {
provider = google-beta
display_name = "ci-cloud-storage-folder"
parent = "folders/${var.folder_id}"
deletion_protection = false
}

module "autokey-project" {
source = "terraform-google-modules/project-factory/google"
version = "~> 18.0"

name = "ci-cloud-storage-autokey"
random_project_id = "true"
org_id = var.org_id
folder_id = google_folder.autokey_folder.folder_id
billing_account = var.billing_account
deletion_policy = "DELETE"

activate_apis = [
"cloudkms.googleapis.com",
]
}

resource "time_sleep" "wait_enable_service_api" {
depends_on = [module.autokey-project]
create_duration = "30s"
}

resource "google_project_service_identity" "kms_service_agent" {
provider = google-beta
service = "cloudkms.googleapis.com"
project = module.autokey-project.project_id
depends_on = [time_sleep.wait_enable_service_api]
}

resource "time_sleep" "wait_service_agent" {
depends_on = [google_project_service_identity.kms_service_agent]
create_duration = "10s"
}

resource "google_project_iam_member" "autokey_project_admin" {
provider = google-beta
project = module.autokey-project.project_id
role = "roles/cloudkms.admin"
member = "serviceAccount:service-${module.autokey-project.project_number}@gcp-sa-cloudkms.iam.gserviceaccount.com"
depends_on = [time_sleep.wait_service_agent]
}

resource "time_sleep" "wait_srv_acc_permissions" {
create_duration = "10s"
depends_on = [google_project_iam_member.autokey_project_admin]
}
8 changes: 8 additions & 0 deletions test/setup/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,11 @@ output "sa_key" {
value = google_service_account_key.int_test.private_key
sensitive = true
}

output "key_project_id" {
value = module.autokey-project.project_id
}

output "folder_id" {
value = google_folder.autokey_folder.folder_id
}