From 68c18f47de6fd7a07ce52f13d5911dab52778435 Mon Sep 17 00:00:00 2001 From: Nuru Date: Sun, 7 May 2023 17:06:39 -0700 Subject: [PATCH] Enhance lifecycle object with optionals, limit length of bucket name (#87) --- README.md | 3 +- docs/terraform.md | 3 +- examples/complete/fixtures.us-east-2.tfvars | 17 ++++++++-- examples/complete/variables.tf | 35 ++++++++++++++++----- main.tf | 14 ++++++++- variables.tf | 32 +++++++++++++++---- 6 files changed, 85 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 9175290..761c10a 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,7 @@ Available targets: | Name | Source | Version | |------|--------|---------| | [aws\_s3\_bucket](#module\_aws\_s3\_bucket) | cloudposse/s3-bucket/aws | 3.1.0 | +| [bucket\_name](#module\_bucket\_name) | cloudposse/label/null | 0.25.0 | | [this](#module\_this) | cloudposse/label/null | 0.25.0 | ## Resources @@ -246,7 +247,7 @@ Available targets: | [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | | [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | | [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no | -| [lifecycle\_configuration\_rules](#input\_lifecycle\_configuration\_rules) | A list of S3 bucket v2 lifecycle rules, as specified in [terraform-aws-s3-bucket](https://github.com/cloudposse/terraform-aws-s3-bucket)"
These rules are not affected by the deprecated `lifecycle_rule_enabled` flag.
**NOTE:** Unless you also set `lifecycle_rule_enabled = false` you will also get the default deprecated rules set on your bucket. |
list(object({
enabled = bool
id = string

abort_incomplete_multipart_upload_days = number

# `filter_and` is the `and` configuration block inside the `filter` configuration.
# This is the only place you should specify a prefix.
filter_and = any
expiration = any
transition = list(any)

noncurrent_version_expiration = any
noncurrent_version_transition = list(any)
}))
| `[]` | no | +| [lifecycle\_configuration\_rules](#input\_lifecycle\_configuration\_rules) | A list of S3 bucket v2 lifecycle rules, as specified in [terraform-aws-s3-bucket](https://github.com/cloudposse/terraform-aws-s3-bucket)"
These rules are not affected by the deprecated `lifecycle_rule_enabled` flag.
**NOTE:** Unless you also set `lifecycle_rule_enabled = false` you will also get the default deprecated rules set on your bucket. |
list(object({
enabled = bool
id = string

abort_incomplete_multipart_upload_days = number

# `filter_and` is the `and` configuration block inside the `filter` configuration.
# This is the only place you should specify a prefix.
filter_and = optional(object({
object_size_greater_than = optional(number) # integer >= 0
object_size_less_than = optional(number) # integer >= 1
prefix = optional(string)
tags = optional(map(string))
}))
expiration = optional(object({
date = optional(string) # string, RFC3339 time format, GMT
days = optional(number) # integer > 0
expired_object_delete_marker = optional(bool)
}))
noncurrent_version_expiration = optional(object({
newer_noncurrent_versions = optional(number) # integer > 0
noncurrent_days = optional(number) # integer >= 0
}))
transition = optional(list(object({
date = optional(string) # string, RFC3339 time format, GMT
days = optional(number) # integer >= 0
storage_class = string # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR.
})), [])
noncurrent_version_transition = optional(list(object({
newer_noncurrent_versions = optional(number) # integer >= 0
noncurrent_days = optional(number) # integer >= 0
storage_class = string # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR.
})), [])
}))
| `[]` | no | | [lifecycle\_prefix](#input\_lifecycle\_prefix) | (Deprecated, use `lifecycle_configuration_rules` instead)
Prefix filter. Used to manage object lifecycle events | `string` | `null` | no | | [lifecycle\_rule\_enabled](#input\_lifecycle\_rule\_enabled) | DEPRECATED: Use `lifecycle_configuration_rules` instead.
When `true`, configures lifecycle events on this bucket using individual (now deprecated) variables.
When `false`, lifecycle events are not configured using individual (now deprecated) variables, but `lifecycle_configuration_rules` still apply.
When `null`, lifecycle events are configured using individual (now deprecated) variables only if `lifecycle_configuration_rules` is empty. | `bool` | `null` | no | | [lifecycle\_tags](#input\_lifecycle\_tags) | (Deprecated, use `lifecycle_configuration_rules` instead)
Tags filter. Used to manage object lifecycle events | `map(string)` | `null` | no | diff --git a/docs/terraform.md b/docs/terraform.md index 1bed559..6590c88 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -18,6 +18,7 @@ | Name | Source | Version | |------|--------|---------| | [aws\_s3\_bucket](#module\_aws\_s3\_bucket) | cloudposse/s3-bucket/aws | 3.1.0 | +| [bucket\_name](#module\_bucket\_name) | cloudposse/label/null | 0.25.0 | | [this](#module\_this) | cloudposse/label/null | 0.25.0 | ## Resources @@ -66,7 +67,7 @@ | [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | | [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | | [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no | -| [lifecycle\_configuration\_rules](#input\_lifecycle\_configuration\_rules) | A list of S3 bucket v2 lifecycle rules, as specified in [terraform-aws-s3-bucket](https://github.com/cloudposse/terraform-aws-s3-bucket)"
These rules are not affected by the deprecated `lifecycle_rule_enabled` flag.
**NOTE:** Unless you also set `lifecycle_rule_enabled = false` you will also get the default deprecated rules set on your bucket. |
list(object({
enabled = bool
id = string

abort_incomplete_multipart_upload_days = number

# `filter_and` is the `and` configuration block inside the `filter` configuration.
# This is the only place you should specify a prefix.
filter_and = any
expiration = any
transition = list(any)

noncurrent_version_expiration = any
noncurrent_version_transition = list(any)
}))
| `[]` | no | +| [lifecycle\_configuration\_rules](#input\_lifecycle\_configuration\_rules) | A list of S3 bucket v2 lifecycle rules, as specified in [terraform-aws-s3-bucket](https://github.com/cloudposse/terraform-aws-s3-bucket)"
These rules are not affected by the deprecated `lifecycle_rule_enabled` flag.
**NOTE:** Unless you also set `lifecycle_rule_enabled = false` you will also get the default deprecated rules set on your bucket. |
list(object({
enabled = bool
id = string

abort_incomplete_multipart_upload_days = number

# `filter_and` is the `and` configuration block inside the `filter` configuration.
# This is the only place you should specify a prefix.
filter_and = optional(object({
object_size_greater_than = optional(number) # integer >= 0
object_size_less_than = optional(number) # integer >= 1
prefix = optional(string)
tags = optional(map(string))
}))
expiration = optional(object({
date = optional(string) # string, RFC3339 time format, GMT
days = optional(number) # integer > 0
expired_object_delete_marker = optional(bool)
}))
noncurrent_version_expiration = optional(object({
newer_noncurrent_versions = optional(number) # integer > 0
noncurrent_days = optional(number) # integer >= 0
}))
transition = optional(list(object({
date = optional(string) # string, RFC3339 time format, GMT
days = optional(number) # integer >= 0
storage_class = string # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR.
})), [])
noncurrent_version_transition = optional(list(object({
newer_noncurrent_versions = optional(number) # integer >= 0
noncurrent_days = optional(number) # integer >= 0
storage_class = string # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR.
})), [])
}))
| `[]` | no | | [lifecycle\_prefix](#input\_lifecycle\_prefix) | (Deprecated, use `lifecycle_configuration_rules` instead)
Prefix filter. Used to manage object lifecycle events | `string` | `null` | no | | [lifecycle\_rule\_enabled](#input\_lifecycle\_rule\_enabled) | DEPRECATED: Use `lifecycle_configuration_rules` instead.
When `true`, configures lifecycle events on this bucket using individual (now deprecated) variables.
When `false`, lifecycle events are not configured using individual (now deprecated) variables, but `lifecycle_configuration_rules` still apply.
When `null`, lifecycle events are configured using individual (now deprecated) variables only if `lifecycle_configuration_rules` is empty. | `bool` | `null` | no | | [lifecycle\_tags](#input\_lifecycle\_tags) | (Deprecated, use `lifecycle_configuration_rules` instead)
Tags filter. Used to manage object lifecycle events | `map(string)` | `null` | no | diff --git a/examples/complete/fixtures.us-east-2.tfvars b/examples/complete/fixtures.us-east-2.tfvars index caa2a78..902401f 100644 --- a/examples/complete/fixtures.us-east-2.tfvars +++ b/examples/complete/fixtures.us-east-2.tfvars @@ -15,9 +15,12 @@ lifecycle_configuration_rules = [ abort_incomplete_multipart_upload_days = 1 # number - filter_and = null - expiration = null - transition = null + # filter_and = null + # expiration = null + # transition = null + filter_and = { + prefix = "prefix/" + } noncurrent_version_expiration = { newer_noncurrent_versions = 3 # integer > 0 noncurrent_days = 90 # integer >= 0 @@ -27,5 +30,13 @@ lifecycle_configuration_rules = [ noncurrent_days = 30 # integer >= 0 storage_class = "ONEZONE_IA" # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR. }] + }, + { + enabled = true + id = "cleanup-delete-markers" + expiration = { + expired_object_delete_marker = true + } + abort_incomplete_multipart_upload_days = 1 } ] diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index 2170463..71fd46f 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -17,17 +17,38 @@ variable "lifecycle_configuration_rules" { # `filter_and` is the `and` configuration block inside the `filter` configuration. # This is the only place you should specify a prefix. - filter_and = any - expiration = any - transition = list(any) - - noncurrent_version_expiration = any - noncurrent_version_transition = list(any) + filter_and = optional(object({ + object_size_greater_than = optional(number) # integer >= 0 + object_size_less_than = optional(number) # integer >= 1 + prefix = optional(string) + tags = optional(map(string)) + })) + expiration = optional(object({ + date = optional(string) # string, RFC3339 time format, GMT + days = optional(number) # integer > 0 + expired_object_delete_marker = optional(bool) + })) + noncurrent_version_expiration = optional(object({ + newer_noncurrent_versions = optional(number) # integer > 0 + noncurrent_days = optional(number) # integer >= 0 + })) + transition = optional(list(object({ + date = optional(string) # string, RFC3339 time format, GMT + days = optional(number) # integer >= 0 + storage_class = string # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR. + })), []) + noncurrent_version_transition = optional(list(object({ + newer_noncurrent_versions = optional(number) # integer >= 0 + noncurrent_days = optional(number) # integer >= 0 + storage_class = string # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR. + })), []) })) - default = [] + description = <<-EOT A list of S3 bucket v2 lifecycle rules, as specified in [terraform-aws-s3-bucket](https://github.com/cloudposse/terraform-aws-s3-bucket)" These rules are not affected by the deprecated `lifecycle_rule_enabled` flag. **NOTE:** Unless you also set `lifecycle_rule_enabled = false` you will also get the default deprecated rules set on your bucket. EOT + default = [] + nullable = false } diff --git a/main.tf b/main.tf index e0fee6d..eae4b67 100644 --- a/main.tf +++ b/main.tf @@ -1,8 +1,20 @@ locals { # We do not use coalesce() here because it is OK if local.bucket_name is empty. - bucket_name = var.bucket_name == null || var.bucket_name == "" ? module.this.id : var.bucket_name + bucket_name = var.bucket_name == null || var.bucket_name == "" ? module.bucket_name.id : var.bucket_name } +module "bucket_name" { + source = "cloudposse/label/null" + version = "0.25.0" + + enabled = local.enabled && try(length(var.bucket_name) == 0, false) + + id_length_limit = 63 # https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html + + context = module.this.context +} + + module "aws_s3_bucket" { source = "cloudposse/s3-bucket/aws" version = "3.1.0" diff --git a/variables.tf b/variables.tf index 921507f..f56a88e 100644 --- a/variables.tf +++ b/variables.tf @@ -172,13 +172,33 @@ variable "lifecycle_configuration_rules" { # `filter_and` is the `and` configuration block inside the `filter` configuration. # This is the only place you should specify a prefix. - filter_and = any - expiration = any - transition = list(any) - - noncurrent_version_expiration = any - noncurrent_version_transition = list(any) + filter_and = optional(object({ + object_size_greater_than = optional(number) # integer >= 0 + object_size_less_than = optional(number) # integer >= 1 + prefix = optional(string) + tags = optional(map(string)) + })) + expiration = optional(object({ + date = optional(string) # string, RFC3339 time format, GMT + days = optional(number) # integer > 0 + expired_object_delete_marker = optional(bool) + })) + noncurrent_version_expiration = optional(object({ + newer_noncurrent_versions = optional(number) # integer > 0 + noncurrent_days = optional(number) # integer >= 0 + })) + transition = optional(list(object({ + date = optional(string) # string, RFC3339 time format, GMT + days = optional(number) # integer >= 0 + storage_class = string # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR. + })), []) + noncurrent_version_transition = optional(list(object({ + newer_noncurrent_versions = optional(number) # integer >= 0 + noncurrent_days = optional(number) # integer >= 0 + storage_class = string # string/enum, one of GLACIER, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, DEEP_ARCHIVE, GLACIER_IR. + })), []) })) + description = <<-EOT A list of S3 bucket v2 lifecycle rules, as specified in [terraform-aws-s3-bucket](https://github.com/cloudposse/terraform-aws-s3-bucket)" These rules are not affected by the deprecated `lifecycle_rule_enabled` flag.