diff --git a/README.md b/README.md new file mode 100644 index 0000000..2058365 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# Google Cloud Storage Module + +## Example + +```hcl +module "buckets" { + source = "./modules/gcs" + project_id = "myproject" + prefix = "test" + names = ["bucket-one", "bucket-two"] + bucket_policy_only = { + bucket-one = false + } + iam_members = { + bucket-two = { + "roles/storage.admin" = ["group:storage@example.com"] + } + } + iam_roles = { + bucket-two = ["roles/storage.admin"] + } +} +``` + + +## Variables + +| name | description | type | required | default | +|---|---|:---: |:---:|:---:| +| names | Bucket name suffixes. | list(string) | ✓ | | +| project_id | Bucket project id. | string | ✓ | | +| *bucket_policy_only* | Optional map to disable object ACLS keyed by name, defaults to true. | map(bool) | | {} | +| *force_destroy* | Optional map to set force destroy keyed by name, defaults to false. | map(bool) | | {} | +| *iam_members* | IAM members keyed by bucket name and role. | map(map(list(string))) | | null | +| *iam_roles* | IAM roles keyed by bucket name. | map(list(string)) | | null | +| *labels* | Labels to be attached to all buckets. | map(string) | | {} | +| *location* | Bucket location. | string | | EU | +| *prefix* | Prefix used to generate the bucket name. | string | | | +| *storage_class* | Bucket storage class. | string | | MULTI_REGIONAL | +| *versioning* | Optional map to set versioning keyed by name, defaults to false. | map(bool) | | {} | + +## Outputs + +| name | description | sensitive | +|---|---|:---:| +| bucket | Bucket resource (for single use). | | +| buckets | Bucket resources. | | +| name | Bucket name (for single use). | | +| names | Bucket names. | | +| names_list | List of bucket names. | | +| url | Bucket URL (for single use). | | +| urls | Bucket URLs. | | +| urls_list | List of bucket URLs. | | + diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..baff11d --- /dev/null +++ b/main.tf @@ -0,0 +1,62 @@ +/** + * 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. + */ + +locals { + buckets = ( + local.has_buckets + ? [for name in var.names : google_storage_bucket.buckets[name]] + : [] + ) + # needed when destroying + has_buckets = length(google_storage_bucket.buckets) > 0 + iam_pairs = var.iam_roles == null ? [] : flatten([ + for name, roles in var.iam_roles : + [for role in roles : { name = name, role = role }] + ]) + iam_keypairs = { + for pair in local.iam_pairs : + "${pair.name}-${pair.role}" => pair + } + iam_members = var.iam_members == null ? {} : var.iam_members + prefix = var.prefix == "" ? "" : join("-", [var.prefix, lower(var.location), ""]) +} + +resource "google_storage_bucket" "buckets" { + for_each = toset(var.names) + name = "${local.prefix}${lower(each.key)}" + project = var.project_id + location = var.location + storage_class = var.storage_class + force_destroy = lookup(var.force_destroy, each.key, false) + bucket_policy_only = lookup(var.bucket_policy_only, each.key, true) + versioning { + enabled = lookup(var.versioning, each.key, false) + } + labels = merge(var.labels, { + location = lower(var.location) + name = lower(each.key) + storage_class = lower(var.storage_class) + }) +} + +resource "google_storage_bucket_iam_binding" "bindings" { + for_each = local.iam_keypairs + bucket = google_storage_bucket.buckets[each.value.name].name + role = each.value.role + members = lookup( + lookup(local.iam_members, each.value.name, {}), each.value.role, [] + ) +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..9a8f8df --- /dev/null +++ b/outputs.tf @@ -0,0 +1,63 @@ +/** + * 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. + */ + +output "bucket" { + description = "Bucket resource (for single use)." + value = local.has_buckets ? local.buckets[0] : null +} + +output "name" { + description = "Bucket name (for single use)." + value = local.has_buckets ? local.buckets[0].name : null +} + +output "url" { + description = "Bucket URL (for single use)." + value = local.has_buckets ? local.buckets[0].url : null +} + +output "buckets" { + description = "Bucket resources." + value = local.buckets +} + +output "names" { + description = "Bucket names." + value = ( + local.has_buckets + ? zipmap(var.names, [for b in local.buckets : lookup(b, "name", null)]) + : {} + ) +} + +output "urls" { + description = "Bucket URLs." + value = ( + local.has_buckets + ? zipmap(var.names, [for b in local.buckets : b.url]) + : {} + ) +} + +output "names_list" { + description = "List of bucket names." + value = [for b in local.buckets : b.name] +} + +output "urls_list" { + description = "List of bucket URLs." + value = [for b in local.buckets : b.name] +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..6cc712e --- /dev/null +++ b/variables.tf @@ -0,0 +1,79 @@ +/** + * 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 "bucket_policy_only" { + description = "Optional map to disable object ACLS keyed by name, defaults to true." + type = map(bool) + default = {} +} + +variable "force_destroy" { + description = "Optional map to set force destroy keyed by name, defaults to false." + type = map(bool) + default = {} +} + +variable "iam_members" { + description = "IAM members keyed by bucket name and role." + type = map(map(list(string))) + default = null +} + +variable "iam_roles" { + description = "IAM roles keyed by bucket name." + type = map(list(string)) + default = null +} + +variable "labels" { + description = "Labels to be attached to all buckets." + type = map(string) + default = {} +} + +variable "location" { + description = "Bucket location." + type = string + default = "EU" +} + +variable "names" { + description = "Bucket name suffixes." + type = list(string) +} + +variable "prefix" { + description = "Prefix used to generate the bucket name." + type = string + default = "" +} + +variable "project_id" { + description = "Bucket project id." + type = string +} + +variable "storage_class" { + description = "Bucket storage class." + type = string + default = "MULTI_REGIONAL" +} + +variable "versioning" { + description = "Optional map to set versioning keyed by name, defaults to false." + type = map(bool) + default = {} +} diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..ce6918e --- /dev/null +++ b/versions.tf @@ -0,0 +1,19 @@ +/** + * 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.12.6" +}